Erstellen eines neuen SVG-Widgets

Es ist möglich ein neues, individuelles SVG-Widget aus einer SVG-Datei zu erstellen.

Zunächst muss die SVG-Datei selektiert werden. Eine exzellente Ressource hierfür ist die im Bilderverzeichniss integrierte Industry Graphic Library.

Das ausgewählte SVG wird nun in dem data/WebUI/widgets-Ordner gespeichert. Zudem wird pro Widget eine eigene JSON-Datei gleichen Namens benötigt. Alle umsetzbaren Widgets werden automatisch ausgelesen, daher erscheint das SVG mit dem Erstellen der Datei in der Liste der verfügbaren Widgets im Dashboard.

Neue SVG-Widgets können auch über das Dashboard selbst hinzugefügt werden. Hierfür wird das Edit Menü geöffnet und ein Datenpunkt ausgewählt, für den das Widget hinzugefügt wird. Dies öffnet den Widget Selector, in dem sich in der rechten oberen Ecke die Option Widget hinzufügen befindet. Diese öffnet den Dialog zum Hinzufügen des eigenen Widgets. Die Dateien müssen als Zip-Packet vorliegen. Es sind die folgenden Strukturen innerhalb des Packets zulässig:

  • widgets (Ordner)
    • widget JSON file (Z.B.: label.json)
    • widget SVG file (Z.B.: label.svg)
  • Komponenten (Ordner, optional > außer, wenn eine "moduleFederationSettings"-Eigenschaft in der JSON-Datei ist)
    • <widgetname> (Ordner, Z.B.: label)
      • Dateien für die Module Federation
  • msg (Ordner, optional)
    • <lang> (z.B.: de_AT.utf8)
      • JSON- oder cat-Dateien
Abbildung 1. Upload-Dialog

Das Verhalten für den versuchten Upload von Dateien, die ein bereits bestehendes Widget überschreiben würden, kann mit dem etm.widget.upload Request gesteuert werden. Der Erste Parameter hierbei ist "archive", welches das Base64-kodierte ZIP-Archiv mit den Dateien enthält. Der zweite Parameter ist der optionale "overwrite". Wird dieser auf "true" gesetzt, werden die vorhandenen Dateien im Produktverzeichnis überschreiben. Bei der Standardeinstellung "false" wird ein Fehler ausgegeben und kein Upload durchgeführt.

Anmerkung:

Es gibt derzeit noch keine Rückmeldung, ob die JSON-Datei fehlerhaft ist. Sollte das Widget nicht erscheinen, prüfen Sie die Gültigkeit der JSON-Datei.

Kommentare sind innerhalb der JSON-Datei nicht erlaubt und machen sie ungültig.

Widget Definitionsdateien können auch in Unterverzeichnissen von data/WebUI/widgets hinzugefügt werden. Diese Dateien inkludieren den relativen Pfad im Widgetnamen, der vom etm.widget.list Request zurückgegeben wird (z.B.: für die Widgetdefinitionsdatei data/WebUI/widget/sub1/gauge.json ist der resultierende, zurückgegebene Name "sub1/gauge"). Sowohl die JSON- als auch die SVG-Dateien für die Widgets müssen sich im selben Ordner befinden.

Wenn ein Request erhalten wird und das letzte Update der gecachten Widgetinformationen älter als 30 Sekunden ist, wird der Cache erneuert und die neuen oder veränderten Widgets werden hinzugefügt. Zusätzlich kann der optionale Parameter "forceUpdate" in den Requestparametern auf "true" gesetzt werden, um ein umgehendes Update der gecachten Widgetinformationen zu erzwingen. Dies ist nur für das aktuelle Projekt gültig, und wird nicht für Subprojekte oder die Version, für welche das Widgetcache nur einmal beim Serverstart initialisiert wird, verwendet.

Struktur der JSON-Datei

Die JSON-Datei enthält die Instruktionen, wie sich das Widget verhalten soll.

Types

Dies definiert den Datentyp, den das Widget erhalten kann. Es kann einer oder mehrere von "float", "uint", "ulong", "long", "int", "bool" oder "string" sein. Ebenfalls sind vorhandene Datenpunktstruktur- oder Strukturtypnamen zulässig.

WidgetType

Die Beschreibung des Widget-types. Für ein neues SVG-Widget muss dies "svg" bleiben.

Label

Das Label, welches für das Widget angezeigt wird, in den Projektsprachen.

Description

Die Beschreibung des Widgets, in den Projektsprachen.

Size

Die minimale Größe, die dein Widget dieses Types innerhalb des Rasters im Dashboard einnimmt. Dies wird als "minRows" und "minCols" angegeben. Das Maximum hierbei sind 25 Zeilen und 25 Spalten.

Inputs

Jedes Widget kann ein oder mehrere Datenpunkte verwenden. Diese werden als Inputs bezeichnet.

Name

Der spezifische Name des Inputs. Er wird verwendet, um diesen anzusprechen, und darf daher keine Sonderzeichen oder Leerzeichen enthalten.

Label

Die Beschreibung der Widget-Regeln in den Projektsprachen.

DPE

Dieser Parameter kann verwendet werden, um einzelne Datenpunkte einer Struktur direkt vorzubefüllen. Sollen keine Datenpunkte vorausgefüllt werden, wird er als "" gesetzt. Innerhalb des Dashboards wird der verfügbare Wertebereich für das Widget automatisch angezeigt.

Description

Die Beschreibung, welche Unterhalb des Datenpunktselektors angezeigt wird. Sie wird auch in den jeweiligen Projektsprachen angezeigt.

AllowRuleOverride

Dieser Parameter bestimmt, ob die festgelegten Regeln überschrieben werden können. Wird dieses Flag auf "false" gesetzt, hat man im Dashboard keine Möglichkeit die Regeln zu modifizieren oder zu erweitern.

Rules

Die vordefinierten Regeln, welche das Verhalten des Widgets bestimmen. Wird dies leer gelassen, existieren keine vordefinierten Regeln für das Widget. Hiermit müssen alle Regeln manuell im Dashboard erstellt werden.

Die Regeln werden mit einem logischen Operator ("operator"), einem zugehörigen Wert("value") und den dann ausgeführten Aktionen("actions") definiert. Hierbei bezieht sich der Wert der Regel immer auf den Wert bzw. den Status des gewählten Datenpunktes.

Die Aktionen selbst werden wiederum mit dem Selektor, der Eigenschaft und dem Wert kontrolliert. Der Selektor ("selector") bestimmt, welcher Teil des SVGs verändert wird. Als Selektor sind einfache CSS-Klassen (diese werden mit führendem Punkt angegeben), HTML IDs (welche mit einer führenden Raute # definiert werden) oder ganze Javascript-Selektoren (z.B.: "#elementid > path:nth-child(7)") erlaubt. Als Unterstützung wird beim Klick in das Selektor-Feld eine Liste mit im SVG gefundenen Selektoren angezeigt. Die zugehörige Eigenschaft ("property") definiert welche der Eigenschaften dieses Teils verändert wird. Die möglichen Eigenschaften sind von dem jeweils betreffenden Element abhängig (z.B.: kann die "fill"-Eigenschaft für Elemente vom Typ "rect" oder "polygon" verwendet werden. Um ein "text"-Element zu befüllen, kann das Attribut "textContent" verwendet werden). Beim Klick auf das Eigenschaftsfeld wird eine Liste der 5 meistgenutzten Eigenschaften mit ihren Beschreibungen und Standardwerten angezeigt. Der Wert ("value") bestimmt wie diese Änderung aussieht. Eine Regel kann mehrere Aktionen enthalten, wofür dann mehrere Aktionsbereiche angelegt werden. Ein Beispiel hierfür kann in der Sektion unterhalb gefunden werden.

SvgFile

Der Pfad und der Name der SVG-Datei, welche für das Widget verwendet wird. Diese Datei wird als Vorschau und Basis des Widgets verwendet.

AllowStructureDrop

Dieser Parameter gibt an, ob das Widget zusätzlich zu normalen Datenpunkten, auch die Verwendung einer Datenpunkt-Struktur akzeptiert.

Erstellen eines neuen SVG-Widgets - Beispiel

Die exisiterenden Widgets im data/WebUI/widgets Ordner können als Beispiele herangezogen werden. Einige Widgets, so wie das Ampel-Widget, sind bereits Implementierungen eines SVG-Widgets. Auch alle anderen Widgets folgen größtenteils der gleichen Struktur und können ebenfalls als Anschauungsmaterial dienen.

Beispielsweise wird hier eine der Regeln für das Ampel-Widget beschrieben:

{
  "operator": "is",
  "value": 2,
  "actions": [
    {
      "selector": ".red-active",
      "property": "opacity",
      "value": "0"
    },
    {
      "selector": ".yellow-active",
      "property": "opacity",
      "value": "0"
    },
    {
      "selector": ".green-active",
      "property": "opacity",
      "value": "1"
    }
  ]
}

Diese Regel wird verwendet, um das grüne Element innerhalb des SVGs zu aktivieren, wenn der Wert des korrespondierenden Datenpunkts 2 annimmt.

Der Operator "is" gemeinsam mit dem Wert "2" bedeutet, dass die nachfolgende Regel dann ausgeführt wird, sobald der Datenpunkt genau den Wert 2 erreicht.

Diese Regel hat 3 zugeordnete "actions". Jede dieser Aktionen betrifft eine der runden Elemente, welche die Lichter der Ampel aufhellen. Die erste Aktion zielt mit der Bezeichnung ".red-active" im "selector" auf das rote Element. Hierbei wird die Eigenschaft "opacity" verändert. Diese Deckkraft wird auf "0" gesetzt und das Element damit entfernt. Ebenso wir die Deckkraft des gelben Elements behandelt. Das grüne Element wird auf "1" gesetzt, womit dieses ganz angezeigt wird.

Verwendung von Variablen

Sowohl im Regel- als auch im Aktionen-Teil können vorhandene Konfigurationsattribute des Datenpunktes als Variablen verwendet werden.

In den Widget-Settings direkt unterhalb des selektierten Datenpunktes, und beim Klick in eines der "value" Eingabefelder werden alle vorhandenen Variablen aufgelistet.

Beispiel:

{
  "operator": "between",
  "value": { "from": "{min}, "to": "{max}" },
  "actions": [
    {
      "selector": ".left-tank",
      "property": "fill",
      "value": "{alertrange_1_color}"
    }
  ]
},

In diesem Beispiel wird der Operator "between" verwendet, um zu prüfen ob der Datenpunktwert zwischen "{min}" und "{max}" - also der definierten PV Range-Konfiguration liegt. Trifft dies zu, wird die Sektion ".left-tank" in der definierten Alarmfarbe eingefärbt.

Verwendung von Funktionen

Es ist auch möglich einfache CSS-Funktionen innerhalb der Aktionen auszuführen. Dies kann hilfreich sein, um Elemente im SVG richtig zu positionieren oder zu skalieren.

Beispiel:

{
  "operator": "always",
  "value": "",
  "actions": [
    {
      "property": "style",
      "selector": "#rect1",
      "value": "transform: translate(22.8px, 51.8px) scaley(clamp(0, calc(1 - ({value} - {min}) / ({max} - {min})), 1))"
    },
    {
      "property": "fill",
      "selector": "#rect2",
      "value": "url(#gradient1)"
    },
  ]
},

In diesem Beispiel wird der Operator "always" verwendet, um die betreffenden Aktionen bei jeder Wertänderung auszuführen. Das Element mit der HTML ID "#rect" wird dabei über die CSS-Eigenschaft "transform" zuerst verschoben ("translate") und danach mit "scaley" in der Höhe verändert. In der Berechnung danach wird der normalisierte Datenpunktwert in einen Wertebereich zwischen 0 und 1 interpoliert.

Wichtig dabei ist, dass diese CSS-Funktionen nur in Verbindung mit dem "style" property funktionieren. Es wäre auch möglich direkt die "transform"-Funktion der SVG-Elemente zu nutzen, jedoch werden an dieser Stelle keine CSS-Funktionen wie "calc", "max", oder "clamp" unterstützt.

Um beispielsweise einen im SVG-definierten Farbverlauf wiederzuverwenden, kann wie in der zweiten Aktion ersichtlich, die "url()" Funktion verwendet werden.