Ein Sankey-Diagramm ist ein Flussdiagramm, das Mengen oder Ströme zwischen Prozessen zeigt. Die Pfeilbreite zeigt die Größe der Flüsse. Es ist nützlich für die Analyse von Energie- und Materialbilanzen und zeigt komplexe Zusammenhänge leicht verständlich. Auch Bereich Finanzen finden sich interessante Einsatzmöglichketen.
Da ich für Blazor kein Sankey Diagramm gefunden habe (nicht einmal bei den hier genannten kostenpflichtigen Angeboten), habe ich mich entschlossen selbst eine Komponente zu erstellen.
Das Blazor Sankey Diagramm soll frei verfügbar als Open Source für Jedermann bereit stehen.
Inhalt
Zielsetzung
Für die Umsetzung der Komponente sind mir ein paar Punkte besonders wichtig, die unbedingt berücksichtigt werden sollen:
- Flexibel nutzbar / erweiterbar
- Ansprechendes Aussehen
- Weitestgehender Verzicht auf JavaScript
- Muss sowohl unter Blazor Server als auch unter Blazor WebAssembly laufen
- Open Source
Umsetzung
Das Repository findest du unter https://github.com/crispycode-net/BlazorSankey
Der Code ist zu weiten Teilen stark von d3-sankey von Mike Bostock inspiriert. Bei der Komponente handelt es sich um eine Implementierung in JavaScript, die das d3 Framework nutzt. Der einfachste Weg wäre sicher ein Wrapper um diese Komponente gewesen um ein Blazor Sankey Diagramm zu bekommen. Es gibt viele gute Beschreibungen dazu, wie man JavaScript Komponenten in Blazor einbindet. Darauf möchte ich hier nicht weiter eingehen.
Der aktuelle Stand ist noch sehr rudimentär, aber ein paar einfache Anwendungsfälle sollten sich mit der Komponente schon umsetzen lassen. Immerhin ist der Screenshot oben schon ein echtes Ergebnis der Komponente. Da bei Open Source Projekten immer zu wenig Zeit übrig ist, um alle Wünsche in die Tat umzusetzen, nehme ich auch gerne Unterstützung in Form von Pull Requests oder Anregungen an. Wer Fragen oder Anregungen hat, kann mich gerne anschreiben oder einen Kommentar hier oder bei GitHub hinterlassen.
Verwendung
Das Blazor Sankey Diagramm bei nuget geladen werden: CrispyCode.BlazorSankey
Die Nutzung der Komponente in eigenen Projekten sollte sehr einfach sein
- nuget Paket gerunterladen
- Ein using statement hinuzufügen
- Die Komponente irgendwo in einer .razor Datei einbinden
- Daten für Nodes und Links als Parameter übergeben
Der folgende Abschnitt zeigt ein einfaches Beispiel:
Man definiert Nodes und Links – hier einfach „hard coded“ um das Beispiel einfach zu halten. Dann fügt man die Komponente im Razor der eigenen Anwendung ein und übergibt ihr die Referenzen auf eben diese Nodes und Links. Dazu gibt es noch die Parameter „Width“ und „Height“ über die sich in CSS Maßeinheiten die Dimensionen des erstellten Diagramms festlegen lassen. Die Komponente ist so aufgebaut, dass dynamische Angaben vor der Berechnung der absoluten Elementpositionen innerhalb des SVG Elements in ihre Pixel-Werte umgerechnet werden.
Der Punkt „Flexibel nutzbar“ aus meiner Zielsetzung erschöpft sich momentan noch darin, dass die Model Klassen für Nodes und Links ein paar optionale Parameter haben, über die Einfluss auf das Ergebnis genommen werden kann.
Node Konstruktor
Hier einmal der Konstruktor der Node Model Klasse. Eine Node wird im Sankey Diagramm als vertikales Rechteckt dargestellt und ist ein Knotenpunkt, von/zu dem Mengen ab- und zufließen:
Der value
und damit die Höhe der Nodes wird aus allen Ab- und Zuflüssen berechnet. Man kann jedoch einen fixedValue
angeben um eine andere Höhe für die Node zu erzwingen. Das ist dann wichtig, wenn man z.B. eine Start-Node hat, die nicht komplett in weiterführende Nodes aufgelöst wird.
Nach dem gleichen Schema lassen sich für die Nodes auch feste Farben vergeben. Gibt man hier nichts an, wird automatisch in den Farbenkasten „Regenbogen“ gegriffen. Daraus ergibt sich eine gleichmäßige Verteilung der Farbgebung über das Spektrum des Regenbogens – sieht nett aus, aber passt sicher nicht immer.
Ähnliches gilt auch für die Deckkraft (opacity
) und den Text (hoverText
), der beim Überfahren der Node mit der Maus in einem kleinem Popup angezeigt wird.
Link Konstruktor
Ein kurzer Blick auf den Konstruktor der Links zeigt ein ähnliches Schema:
Events
Zur Zeit bietet die Komponente zwei Event Callbacks, an denen man eigene Event Handler registrieren kann: OnNodeClicked
und OnLinkClicked
. OnNodeClicked
wird ausgeführt wenn der User auf den vertikalen Balken klickt, der die Node repräsentiert (nicht auf den Text zur Node). OnLinkClicked
wird ausgeführt bei Click auf den Beziér Pfad, der den Link zwischen zwei Nodes abbildet.
Die Callbacks geben das jeweilige Model Objekt als Parameter mit:
CSS Klassen
Das Styling per CSS Klassen wird an einigen Punkten der Komponente unterstützt. Die SVG Elemente für Links folgen der Hierarchie
- g class links
- g class link
- path class link
- g class link
Dadurch lassen sich vielfältige Anpassungen per CSS erreichen:
Geplante Erweiterungen
Der bisherige Umfang hält vermutlich nur überschaubaren Einsatzanforderungen stand.
Für die kommenden Versionen sind die folgenden Features geplant. Hinterlasse gerne einen Kommentar oder eine Nachricht, wenn du Ideen für weitere Funktionen hast.
Funktionen zur Formatierung
Die Ausgabe der Texte sollten sich über eine Art Pattern steuern lassen. Man könnte die vorgegebenen und berechneten Werte dynamisch in einem Platzhalter verwenden.
Reaktion auf Größenänderung
Bisher wird nach der initialen Abfrage nicht mehr neu berechnet. Das Diagramm sollte sich aber bei Änderungen der Fenstergröße neu berechnen.
Veröffentlichung als Paket
Sobald nicht mehr täglich an dem Paket gearbeitet wird, sollte es zur einfacheren Nutzung als NuGet Paket laden lassen.