{"id":279,"date":"2023-05-05T10:24:59","date_gmt":"2023-05-05T09:24:59","guid":{"rendered":"https:\/\/crispycode.net\/?p=279"},"modified":"2023-05-16T18:09:30","modified_gmt":"2023-05-16T17:09:30","slug":"blazor-sankey-diagramm","status":"publish","type":"post","link":"https:\/\/crispycode.net\/de\/blazor-sankey-diagramm\/","title":{"rendered":"Ein einfach zu nutzendes Blazor Sankey Diagramm"},"content":{"rendered":"\n<p>Ein Sankey-Diagramm ist ein Flussdiagramm, das Mengen oder Str\u00f6me zwischen Prozessen zeigt. Die Pfeilbreite zeigt die Gr\u00f6\u00dfe der Fl\u00fcsse. Es ist n\u00fctzlich f\u00fcr die Analyse von Energie- und Materialbilanzen und zeigt komplexe Zusammenh\u00e4nge leicht verst\u00e4ndlich. Auch Bereich Finanzen finden sich interessante Einsatzm\u00f6glichketen.<\/p>\n\n\n\n<p>Da ich f\u00fcr Blazor kein Sankey Diagramm gefunden habe (nicht einmal bei den <a href=\"https:\/\/crispycode.net\/de\/was-ist-blazor\/\" data-type=\"post\" data-id=\"271\">hier<\/a> genannten kostenpflichtigen Angeboten), habe ich mich entschlossen selbst eine Komponente zu erstellen. <\/p>\n\n\n\n<p>Das Blazor Sankey Diagramm soll frei verf\u00fcgbar als Open Source f\u00fcr Jedermann bereit stehen.<\/p>\n\n\n\n<figure class=\"wp-block-image alignwide size-large\"><img loading=\"lazy\" decoding=\"async\" width=\"1024\" height=\"343\" src=\"https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram-1024x343.webp\" alt=\"Blazor Sankey Diagramm zeigt Trafficfluss im Web\" class=\"wp-image-214\" srcset=\"https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram-1024x343.webp 1024w, https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram-300x101.webp 300w, https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram-768x257.webp 768w, https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram.webp 1200w\" sizes=\"auto, (max-width: 1024px) 100vw, 1024px\" \/><\/figure>\n\n\n<div class=\"bd-thopjeou9a6ovpkt4kwjkh8uwfh10f wp-block-bd--- wp-block-bd-block-44\"><img decoding=\"async\" src=\"https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/alexander-bartz.90x90.jpg\" alt=\"Profilbild Alexander Bartz\" class=\"bd-20hqmwgfd45ft6le7o9jodfn5s4wdr\"><div class=\"bd-h521mx4v22cf4pnhdltwg5jsfoh993\"><span class=\"bd-q4ar1wk0pskc0416tjc7mqgzja7qdd\">Alexander Bartz<\/span><span class=\"bd-ykmon322dena208dhdzhgf1giiesgg\">soft-evolution GmbH &amp; CO KG<\/span><a title=\"LinkedIn Profil Alexander Bartz\" href=\"https:\/\/www.linkedin.com\/in\/alexander-bartz-soft-evolution\/\" class=\"bd-a4t6wfzl4e6eqgll7rkjmpmu1ii5k0\" target=\"_blank\" rel=\"noopener\"><img decoding=\"async\" src=\"https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/linkedin.png\" alt=\"LinkedIn Logo\" class=\"bd-defoi8wzogf1iq3dwx1b54vft4y5fp\"><\/a><\/div><\/div>\n\n\n<div class=\"wp-block-rank-math-toc-block\"><h2>Inhalt<\/h2><nav><ul><li class=\"\"><a href=\"#zielsetzung\">Zielsetzung<\/a><\/li><li class=\"\"><a href=\"#umsetzung\">Umsetzung<\/a><\/li><li class=\"\"><a href=\"#verwendung\">Verwendung<\/a><ul><li class=\"\"><a href=\"#node-konstruktor\">Node Konstruktor<\/a><\/li><li class=\"\"><a href=\"#link-konstruktor\">Link Konstruktor<\/a><\/li><li class=\"\"><a href=\"#events\">Events<\/a><\/li><li class=\"\"><a href=\"#css-klassen\">CSS Klassen<\/a><\/li><\/ul><\/li><li class=\"\"><a href=\"#geplante-erweiterungen\">Geplante Erweiterungen<\/a><ul><li class=\"\"><a href=\"#funktionen-zur-formatierung\">Funktionen zur Formatierung<\/a><\/li><li class=\"\"><a href=\"#reaktion-auf-grossenanderung\">Reaktion auf Gr\u00f6\u00dfen\u00e4nderung<\/a><\/li><li class=\"\"><a href=\"#veroffentlichung-als-paket\">Ver\u00f6ffentlichung als Paket<\/a><\/li><\/ul><\/li><\/ul><\/nav><\/div>\n\n\n\n<div style=\"height:60px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"zielsetzung\">Zielsetzung<\/h2>\n\n\n\n<p>F\u00fcr die Umsetzung der Komponente sind mir ein paar Punkte besonders wichtig, die unbedingt ber\u00fccksichtigt werden sollen:<\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>Flexibel nutzbar \/ erweiterbar<\/li>\n\n\n\n<li>Ansprechendes Aussehen<\/li>\n\n\n\n<li>Weitestgehender Verzicht auf JavaScript<\/li>\n\n\n\n<li>Muss sowohl unter Blazor Server als auch unter Blazor WebAssembly laufen<\/li>\n\n\n\n<li>Open Source<\/li>\n<\/ul>\n\n\n\n<div style=\"height:42px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"umsetzung\">Umsetzung<\/h2>\n\n\n\n<p>Das Repository findest du unter <a href=\"https:\/\/github.com\/crispycode-net\/BlazorSankey\" target=\"_blank\" rel=\"noreferrer noopener\">https:\/\/github.com\/crispycode-net\/BlazorSankey<\/a><\/p>\n\n\n\n<p>Der Code ist zu weiten Teilen stark von <a href=\"https:\/\/github.com\/d3\/d3-sankey\" target=\"_blank\" rel=\"noreferrer noopener\">d3-sankey<\/a> von Mike Bostock inspiriert. Bei der Komponente handelt es sich um eine Implementierung in JavaScript, die das d3 Framework nutzt. Der einfachste Weg w\u00e4re 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\u00f6chte ich hier nicht weiter eingehen.<\/p>\n\n\n\n<p>Der aktuelle Stand ist noch sehr rudiment\u00e4r, aber ein paar einfache Anwendungsf\u00e4lle 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 \u00fcbrig ist, um alle W\u00fcnsche in die Tat umzusetzen, nehme ich auch gerne Unterst\u00fctzung 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.<\/p>\n\n\n\n<div style=\"height:37px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"verwendung\">Verwendung<\/h2>\n\n\n\n<p>Das Blazor Sankey Diagramm bei nuget geladen werden: <code><a href=\"https:\/\/www.nuget.org\/packages\/CrispyCode.BlazorSankey\/\" target=\"_blank\" rel=\"noopener\">CrispyCode.BlazorSankey<\/a><\/code><\/p>\n\n\n<div class=\"wp-block-prettycode-code  \">\n  <header class=\"prettycode-header\">\n    <div class=\"prettycode-lang is-lang-shell\">\n      Shell    <\/div>\n    <div class=\"prettycode-file\">\n          <\/div>\n  <\/header>\n  <textarea\n    class=\"prettycode-source\"\n    name=\"codemirror-454239101\"\n    id=\"codemirror-454239101\"\n  >dotnet add package CrispyCode.BlazorSankey<\/textarea>\n  <script>\n    CodeMirror.fromTextArea( document.getElementById('codemirror-454239101'), {\n      mode: 'shell',\n      readOnly: true,\n      theme: 'hopscotch',\n      lineNumbers: true,\n      firstLineNumber: 1,\n      matchBrackets: true,\n      indentUnit: 4,\n      tabSize: 4,\n      lineWrapping: true,\n    } );\n  <\/script>\n<\/div>\n\n\n\n<p>Die Nutzung der Komponente in eigenen Projekten sollte sehr einfach sein<\/p>\n\n\n\n<ol class=\"wp-block-list\">\n<li>nuget Paket gerunterladen<\/li>\n\n\n\n<li>Ein using statement hinuzuf\u00fcgen<\/li>\n\n\n\n<li>Die Komponente irgendwo in einer .razor Datei einbinden<\/li>\n\n\n\n<li>Daten f\u00fcr Nodes und Links als Parameter \u00fcbergeben<\/li>\n<\/ol>\n\n\n\n<p>Der folgende Abschnitt zeigt ein einfaches Beispiel:<\/p>\n\n\n<div class=\"wp-block-prettycode-code  \">\n  <header class=\"prettycode-header\">\n    <div class=\"prettycode-lang is-lang-c#\">\n      C#    <\/div>\n    <div class=\"prettycode-file\">\n      index.razor    <\/div>\n  <\/header>\n  <textarea\n    class=\"prettycode-source\"\n    name=\"codemirror-1166384845\"\n    id=\"codemirror-1166384845\"\n  >@page &quot;\/&quot;\n@using BlazorSankey.Model;\n\n&lt;SankeyDiagram Width=&quot;100%&quot; Height=&quot;402px&quot; Nodes=&quot;@nodes&quot; Links=&quot;@links&quot;&gt;&lt;\/SankeyDiagram&gt;\n\n@code {\n    private List&lt;Node&gt; nodes = new List&lt;Node&gt; {\n        new Node(1, &quot;Client Devices&quot;, fixedValue: 8000),\n        new Node(2, &quot;Load Balancer&quot;),\n        new Node(3, &quot;Web Server 1&quot;),\n        new Node(4, &quot;Web Server 2&quot;),\n        new Node(5, &quot;Database Server&quot;),\n        new Node(6, &quot;Cache Server&quot;),\n        new Node(7, &quot;Storage Server&quot;),\n        new Node(8, &quot;API Server&quot;),\n        new Node(9, &quot;External Services&quot;)\n    };\n\n    private List&lt;Link&gt; links = new List&lt;Link&gt; {\n        new Link(1, 2, 5000),\n        new Link(2, 3, 2500),\n        new Link(2, 4, 2500),\n        new Link(3, 5, 1000),\n        new Link(3, 6, 1500),\n        new Link(4, 5, 1000),\n        new Link(4, 6, 1500),\n        new Link(5, 7, 2000),\n        new Link(6, 7, 3000),\n        new Link(3, 8, 800),\n        new Link(4, 8, 800),\n        new Link(8, 9, 1600)\n    };\n}<\/textarea>\n  <script>\n    CodeMirror.fromTextArea( document.getElementById('codemirror-1166384845'), {\n      mode: 'clike',\n      readOnly: true,\n      theme: 'darcula',\n      lineNumbers: true,\n      firstLineNumber: 1,\n      matchBrackets: true,\n      indentUnit: 4,\n      tabSize: 4,\n      lineWrapping: true,\n    } );\n  <\/script>\n<\/div>\n\n\n\n<p>Man definiert Nodes und Links &#8211; hier einfach &#8222;hard coded&#8220; um das Beispiel einfach zu halten. Dann f\u00fcgt man die Komponente im Razor der eigenen Anwendung ein und \u00fcbergibt ihr die Referenzen auf eben diese Nodes und Links. Dazu gibt es noch die Parameter &#8222;Width&#8220; und &#8222;Height&#8220; \u00fcber die sich in CSS Ma\u00dfeinheiten 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.<\/p>\n\n\n\n<p>Der Punkt &#8222;Flexibel nutzbar&#8220; aus meiner Zielsetzung ersch\u00f6pft sich momentan noch darin, dass die Model Klassen f\u00fcr Nodes und Links ein paar optionale Parameter haben, \u00fcber die Einfluss auf das Ergebnis genommen werden kann.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"node-konstruktor\">Node Konstruktor<\/h3>\n\n\n\n<p>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\u00dfen:<\/p>\n\n\n<div class=\"wp-block-prettycode-code  \">\n  <header class=\"prettycode-header\">\n    <div class=\"prettycode-lang is-lang-c#\">\n      C#    <\/div>\n    <div class=\"prettycode-file\">\n      Node.cs    <\/div>\n  <\/header>\n  <textarea\n    class=\"prettycode-source\"\n    name=\"codemirror-1802522304\"\n    id=\"codemirror-1802522304\"\n  >public Node(object id, string? name = null, double? fixedValue = null, string? color = null, double opacity = 0.6, string? hoverText = null)\n{\n    Id = id;\n    Name = name;\n    FixedValue = fixedValue;\n    Color = color;\n    Opacity = opacity;\n    HoverText = hoverText;\n}<\/textarea>\n  <script>\n    CodeMirror.fromTextArea( document.getElementById('codemirror-1802522304'), {\n      mode: 'clike',\n      readOnly: true,\n      theme: 'darcula',\n      lineNumbers: true,\n      firstLineNumber: 1,\n      matchBrackets: true,\n      indentUnit: 4,\n      tabSize: 4,\n      lineWrapping: true,\n    } );\n  <\/script>\n<\/div>\n\n\n\n<p>Der <code>value<\/code> und damit die H\u00f6he der Nodes wird aus allen Ab- und Zufl\u00fcssen berechnet. Man kann jedoch einen <code>fixedValue<\/code> angeben um eine andere H\u00f6he f\u00fcr die Node zu erzwingen. Das ist dann wichtig, wenn man z.B. eine Start-Node hat, die nicht komplett in weiterf\u00fchrende Nodes aufgel\u00f6st wird.<\/p>\n\n\n\n<p>Nach dem gleichen Schema lassen sich f\u00fcr die Nodes auch feste Farben vergeben. Gibt man hier nichts an, wird automatisch in den Farbenkasten &#8222;Regenbogen&#8220; gegriffen. Daraus ergibt sich eine gleichm\u00e4\u00dfige Verteilung der Farbgebung \u00fcber das Spektrum des Regenbogens &#8211; sieht nett aus, aber passt sicher nicht immer.<\/p>\n\n\n\n<p>\u00c4hnliches gilt auch f\u00fcr die Deckkraft (<code>opacity<\/code>) und den Text (<code>hoverText<\/code>), der beim \u00dcberfahren der Node mit der Maus in einem kleinem Popup angezeigt wird.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"link-konstruktor\">Link Konstruktor<\/h3>\n\n\n\n<p>Ein kurzer Blick auf  den Konstruktor der Links zeigt ein \u00e4hnliches Schema:<\/p>\n\n\n<div class=\"wp-block-prettycode-code  \">\n  <header class=\"prettycode-header\">\n    <div class=\"prettycode-lang is-lang-c#\">\n      C#    <\/div>\n    <div class=\"prettycode-file\">\n      Link.cs    <\/div>\n  <\/header>\n  <textarea\n    class=\"prettycode-source\"\n    name=\"codemirror-374072006\"\n    id=\"codemirror-374072006\"\n  >public Link(object sourceId, object targetId, double value, string? title = null, string? startColor = null, string? endColor = null)\n{\n    SourceId = sourceId;\n    TargetId = targetId;\n    Value = value;\n    Title = title;\n    StartColor = startColor;\n    EndColor = endColor;\n}<\/textarea>\n  <script>\n    CodeMirror.fromTextArea( document.getElementById('codemirror-374072006'), {\n      mode: 'clike',\n      readOnly: true,\n      theme: 'darcula',\n      lineNumbers: true,\n      firstLineNumber: 1,\n      matchBrackets: true,\n      indentUnit: 4,\n      tabSize: 4,\n      lineWrapping: true,\n    } );\n  <\/script>\n<\/div>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"events\">Events<\/h3>\n\n\n\n<p>Zur Zeit bietet die Komponente zwei Event Callbacks, an denen man eigene Event Handler registrieren kann: <code>OnNodeClicked <\/code>und <code>OnLinkClicked<\/code>. <code>OnNodeClicked <\/code>wird ausgef\u00fchrt wenn der User auf den vertikalen Balken klickt, der die Node repr\u00e4sentiert (nicht auf den Text zur Node). <code>OnLinkClicked<\/code> wird ausgef\u00fchrt bei Click auf den Bezi\u00e9r Pfad, der den Link zwischen zwei Nodes abbildet.<\/p>\n\n\n<div class=\"wp-block-prettycode-code  \">\n  <header class=\"prettycode-header\">\n    <div class=\"prettycode-lang is-lang-c#\">\n      C#    <\/div>\n    <div class=\"prettycode-file\">\n          <\/div>\n  <\/header>\n  <textarea\n    class=\"prettycode-source\"\n    name=\"codemirror-2073356402\"\n    id=\"codemirror-2073356402\"\n  >&lt;SankeyDiagram \n    &#8230;\n    OnNodeClicked=&quot;NodeClicked&quot; \n    OnLinkClicked=&quot;LinkClicked&quot; \/&gt;<\/textarea>\n  <script>\n    CodeMirror.fromTextArea( document.getElementById('codemirror-2073356402'), {\n      mode: 'clike',\n      readOnly: true,\n      theme: 'darcula',\n      lineNumbers: true,\n      firstLineNumber: 1,\n      matchBrackets: true,\n      indentUnit: 4,\n      tabSize: 4,\n      lineWrapping: true,\n    } );\n  <\/script>\n<\/div>\n\n\n\n<p>Die Callbacks geben das jeweilige Model Objekt als Parameter mit:<\/p>\n\n\n<div class=\"wp-block-prettycode-code  \">\n  <header class=\"prettycode-header\">\n    <div class=\"prettycode-lang is-lang-c#\">\n      C#    <\/div>\n    <div class=\"prettycode-file\">\n          <\/div>\n  <\/header>\n  <textarea\n    class=\"prettycode-source\"\n    name=\"codemirror-1342890222\"\n    id=\"codemirror-1342890222\"\n  >private void NodeClicked(Node node)\n{\n\tConsole.WriteLine($&quot;Node {node.Name} clicked&quot;);\n}\n\nprivate void LinkClicked(Link link)\n{\n\tConsole.WriteLine($&quot;Link {link.pId} clicked&quot;);\n}<\/textarea>\n  <script>\n    CodeMirror.fromTextArea( document.getElementById('codemirror-1342890222'), {\n      mode: 'clike',\n      readOnly: true,\n      theme: 'darcula',\n      lineNumbers: true,\n      firstLineNumber: 1,\n      matchBrackets: true,\n      indentUnit: 4,\n      tabSize: 4,\n      lineWrapping: true,\n    } );\n  <\/script>\n<\/div>\n\n\n\n<div style=\"height:50px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"css-klassen\">CSS Klassen<\/h3>\n\n\n\n<p>Das Styling per CSS Klassen wird an einigen Punkten der Komponente unterst\u00fctzt. Die SVG Elemente f\u00fcr Links folgen der Hierarchie <\/p>\n\n\n\n<ul class=\"wp-block-list\">\n<li>g class links\n<ul class=\"wp-block-list\">\n<li>g class link\n<ul class=\"wp-block-list\">\n<li>path class link<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n<\/li>\n<\/ul>\n\n\n\n<p>Dadurch lassen sich vielf\u00e4ltige Anpassungen per CSS erreichen:<\/p>\n\n\n<div class=\"wp-block-prettycode-code  \">\n  <header class=\"prettycode-header\">\n    <div class=\"prettycode-lang is-lang-css\">\n      CSS    <\/div>\n    <div class=\"prettycode-file\">\n          <\/div>\n  <\/header>\n  <textarea\n    class=\"prettycode-source\"\n    name=\"codemirror-792090339\"\n    id=\"codemirror-792090339\"\n  >g.link {\n    opacity: 0.3;\n}<\/textarea>\n  <script>\n    CodeMirror.fromTextArea( document.getElementById('codemirror-792090339'), {\n      mode: 'css',\n      readOnly: true,\n      theme: 'darcula',\n      lineNumbers: true,\n      firstLineNumber: 1,\n      matchBrackets: true,\n      indentUnit: 4,\n      tabSize: 4,\n      lineWrapping: true,\n    } );\n  <\/script>\n<\/div>\n\n\n<div class=\"wp-block-prettycode-code  \">\n  <header class=\"prettycode-header\">\n    <div class=\"prettycode-lang is-lang-css\">\n      CSS    <\/div>\n    <div class=\"prettycode-file\">\n          <\/div>\n  <\/header>\n  <textarea\n    class=\"prettycode-source\"\n    name=\"codemirror-118062936\"\n    id=\"codemirror-118062936\"\n  >path.link {\n    fill: none;\n    stroke: #ccc;\n    stroke-width: 5px;\n}<\/textarea>\n  <script>\n    CodeMirror.fromTextArea( document.getElementById('codemirror-118062936'), {\n      mode: 'css',\n      readOnly: true,\n      theme: 'darcula',\n      lineNumbers: true,\n      firstLineNumber: 1,\n      matchBrackets: true,\n      indentUnit: 4,\n      tabSize: 4,\n      lineWrapping: true,\n    } );\n  <\/script>\n<\/div>\n\n\n<div class=\"wp-block-prettycode-code  \">\n  <header class=\"prettycode-header\">\n    <div class=\"prettycode-lang is-lang-css\">\n      CSS    <\/div>\n    <div class=\"prettycode-file\">\n          <\/div>\n  <\/header>\n  <textarea\n    class=\"prettycode-source\"\n    name=\"codemirror-1435749866\"\n    id=\"codemirror-1435749866\"\n  >g.node {\n    cursor: pointer;\n}\n\nrect.node {\n    cursor: pointer;\n}<\/textarea>\n  <script>\n    CodeMirror.fromTextArea( document.getElementById('codemirror-1435749866'), {\n      mode: 'css',\n      readOnly: true,\n      theme: 'darcula',\n      lineNumbers: true,\n      firstLineNumber: 1,\n      matchBrackets: true,\n      indentUnit: 4,\n      tabSize: 4,\n      lineWrapping: true,\n    } );\n  <\/script>\n<\/div>\n\n\n<div class=\"wp-block-prettycode-code  \">\n  <header class=\"prettycode-header\">\n    <div class=\"prettycode-lang is-lang-css\">\n      CSS    <\/div>\n    <div class=\"prettycode-file\">\n          <\/div>\n  <\/header>\n  <textarea\n    class=\"prettycode-source\"\n    name=\"codemirror-1838086523\"\n    id=\"codemirror-1838086523\"\n  >    rect.node:hover {\n        stroke: #000;\n        stroke-width: 1.5px;\n    }<\/textarea>\n  <script>\n    CodeMirror.fromTextArea( document.getElementById('codemirror-1838086523'), {\n      mode: 'css',\n      readOnly: true,\n      theme: 'darcula',\n      lineNumbers: true,\n      firstLineNumber: 1,\n      matchBrackets: true,\n      indentUnit: 4,\n      tabSize: 4,\n      lineWrapping: true,\n    } );\n  <\/script>\n<\/div>\n\n\n\n<div style=\"height:57px\" aria-hidden=\"true\" class=\"wp-block-spacer\"><\/div>\n\n\n\n<h2 class=\"wp-block-heading\" id=\"geplante-erweiterungen\">Geplante Erweiterungen<\/h2>\n\n\n\n<p>Der bisherige Umfang h\u00e4lt vermutlich nur \u00fcberschaubaren Einsatzanforderungen stand. <\/p>\n\n\n\n<p>F\u00fcr die kommenden Versionen sind die folgenden Features geplant. Hinterlasse gerne einen Kommentar oder <a href=\"https:\/\/www.codeus.de\/kontakt\/\" data-type=\"page\" data-id=\"107\" target=\"_blank\" rel=\"noopener\">eine Nachricht<\/a>, wenn du Ideen f\u00fcr weitere Funktionen hast.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"funktionen-zur-formatierung\">Funktionen zur Formatierung<\/h3>\n\n\n\n<p>Die Ausgabe der Texte sollten sich \u00fcber eine Art Pattern steuern lassen. Man k\u00f6nnte die vorgegebenen und berechneten Werte dynamisch in einem Platzhalter verwenden.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"reaktion-auf-grossenanderung\">Reaktion auf Gr\u00f6\u00dfen\u00e4nderung<\/h3>\n\n\n\n<p>Bisher wird nach der initialen Abfrage nicht mehr neu berechnet. Das Diagramm sollte sich aber bei \u00c4nderungen der Fenstergr\u00f6\u00dfe neu berechnen.<\/p>\n\n\n\n<h3 class=\"wp-block-heading\" id=\"veroffentlichung-als-paket\">Ver\u00f6ffentlichung als Paket<\/h3>\n\n\n\n<p>Sobald nicht mehr t\u00e4glich an dem Paket gearbeitet wird, sollte es zur einfacheren Nutzung als NuGet Paket laden lassen.<\/p>\n\n\n\n<p><\/p>\n<div class=\"shariff\"><ul class=\"shariff-buttons theme-default orientation-horizontal buttonsize-medium\"><li class=\"shariff-button facebook shariff-nocustomcolor\" style=\"background-color:#4273c8\"><a href=\"https:\/\/www.facebook.com\/sharer\/sharer.php?u=https%3A%2F%2Fcrispycode.net%2Fde%2Fblazor-sankey-diagramm%2F\" title=\"Bei Facebook teilen\" aria-label=\"Bei Facebook teilen\" role=\"button\" rel=\"nofollow\" class=\"shariff-link\" style=\"; background-color:#3b5998; color:#fff\" target=\"_blank\"><span class=\"shariff-icon\" style=\"\"><svg width=\"32px\" height=\"20px\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 18 32\"><path fill=\"#3b5998\" d=\"M17.1 0.2v4.7h-2.8q-1.5 0-2.1 0.6t-0.5 1.9v3.4h5.2l-0.7 5.3h-4.5v13.6h-5.5v-13.6h-4.5v-5.3h4.5v-3.9q0-3.3 1.9-5.2t5-1.8q2.6 0 4.1 0.2z\"\/><\/svg><\/span><span class=\"shariff-text\">teilen<\/span>&nbsp;<\/a><\/li><li class=\"shariff-button linkedin shariff-nocustomcolor\" style=\"background-color:#1488bf\"><a href=\"https:\/\/www.linkedin.com\/sharing\/share-offsite\/?url=https%3A%2F%2Fcrispycode.net%2Fde%2Fblazor-sankey-diagramm%2F\" title=\"Bei LinkedIn teilen\" aria-label=\"Bei LinkedIn teilen\" role=\"button\" rel=\"noopener nofollow\" class=\"shariff-link\" style=\"; background-color:#0077b5; color:#fff\" target=\"_blank\"><span class=\"shariff-icon\" style=\"\"><svg width=\"32px\" height=\"20px\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 27 32\"><path fill=\"#0077b5\" d=\"M6.2 11.2v17.7h-5.9v-17.7h5.9zM6.6 5.7q0 1.3-0.9 2.2t-2.4 0.9h0q-1.5 0-2.4-0.9t-0.9-2.2 0.9-2.2 2.4-0.9 2.4 0.9 0.9 2.2zM27.4 18.7v10.1h-5.9v-9.5q0-1.9-0.7-2.9t-2.3-1.1q-1.1 0-1.9 0.6t-1.2 1.5q-0.2 0.5-0.2 1.4v9.9h-5.9q0-7.1 0-11.6t0-5.3l0-0.9h5.9v2.6h0q0.4-0.6 0.7-1t1-0.9 1.6-0.8 2-0.3q3 0 4.9 2t1.9 6z\"\/><\/svg><\/span><span class=\"shariff-text\">teilen<\/span>&nbsp;<\/a><\/li><li class=\"shariff-button mastodon shariff-nocustomcolor\" style=\"background-color:#563ACC\"><a href=\"https:\/\/s2f.kytta.dev\/?text=Ein%20einfach%20zu%20nutzendes%20Blazor%20Sankey%20Diagramm https%3A%2F%2Fcrispycode.net%2Fde%2Fblazor-sankey-diagramm%2F\" title=\"Bei Mastodon teilen\" aria-label=\"Bei Mastodon teilen\" role=\"button\" rel=\"noopener nofollow\" class=\"shariff-link\" style=\"; background-color:#6364FF; color:#fff\" target=\"_blank\"><span class=\"shariff-icon\" style=\"\"><svg width=\"75\" height=\"79\" viewBox=\"0 0 75 79\" fill=\"none\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\"><path d=\"M37.813-.025C32.462-.058 27.114.13 21.79.598c-8.544.621-17.214 5.58-20.203 13.931C-1.12 23.318.408 32.622.465 41.65c.375 7.316.943 14.78 3.392 21.73 4.365 9.465 14.781 14.537 24.782 15.385 7.64.698 15.761-.213 22.517-4.026a54.1 54.1 0 0 0 .01-6.232c-6.855 1.316-14.101 2.609-21.049 1.074-3.883-.88-6.876-4.237-7.25-8.215-1.53-3.988 3.78-.43 5.584-.883 9.048 1.224 18.282.776 27.303-.462 7.044-.837 14.26-4.788 16.65-11.833 2.263-6.135 1.215-12.79 1.698-19.177.06-3.84.09-7.692-.262-11.52C72.596 7.844 63.223.981 53.834.684a219.453 219.453 0 0 0-16.022-.71zm11.294 12.882c5.5-.067 10.801 4.143 11.67 9.653.338 1.48.471 3 .471 4.515v21.088h-8.357c-.07-7.588.153-15.182-.131-22.765-.587-4.368-7.04-5.747-9.672-2.397-2.422 3.04-1.47 7.155-1.67 10.735v6.392h-8.307c-.146-4.996.359-10.045-.404-15.002-1.108-4.218-7.809-5.565-10.094-1.666-1.685 3.046-.712 6.634-.976 9.936v14.767h-8.354c.109-8.165-.238-16.344.215-24.5.674-5.346 5.095-10.389 10.676-10.627 4.902-.739 10.103 2.038 12.053 6.631.375 1.435 1.76 1.932 1.994.084 1.844-3.704 5.501-6.739 9.785-6.771.367-.044.735-.068 1.101-.073z\"\/><defs><linearGradient id=\"paint0_linear_549_34\" x1=\"37.0692\" y1=\"0\" x2=\"37.0692\" y2=\"79\" gradientUnits=\"userSpaceOnUse\"><stop stop-color=\"#6364FF\"\/><stop offset=\"1\" stop-color=\"#563ACC\"\/><\/linearGradient><\/defs><\/svg><\/span><span class=\"shariff-text\">teilen<\/span>&nbsp;<\/a><\/li><li class=\"shariff-button pinterest shariff-nocustomcolor\" style=\"background-color:#e70f18\"><a href=\"https:\/\/www.pinterest.com\/pin\/create\/link\/?url=https%3A%2F%2Fcrispycode.net%2Fde%2Fblazor-sankey-diagramm%2F&media=https%3A%2F%2Fcrispycode.net%2Fwp-content%2Fuploads%2F2023%2F05%2FBlazor-Sankey-Diagram.webp&description=Ein%20einfach%20zu%20nutzendes%20Blazor%20Sankey%20Diagramm\" title=\"Bei Pinterest pinnen\" aria-label=\"Bei Pinterest pinnen\" role=\"button\" rel=\"noopener nofollow\" class=\"shariff-link\" style=\"; background-color:#cb2027; color:#fff\" target=\"_blank\"><span class=\"shariff-icon\" style=\"\"><svg width=\"32px\" height=\"20px\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 27 32\"><path fill=\"#cb2027\" d=\"M27.4 16q0 3.7-1.8 6.9t-5 5-6.9 1.9q-2 0-3.9-0.6 1.1-1.7 1.4-2.9 0.2-0.6 1-3.8 0.4 0.7 1.3 1.2t2 0.5q2.1 0 3.8-1.2t2.7-3.4 0.9-4.8q0-2-1.1-3.8t-3.1-2.9-4.5-1.2q-1.9 0-3.5 0.5t-2.8 1.4-2 2-1.2 2.3-0.4 2.4q0 1.9 0.7 3.3t2.1 2q0.5 0.2 0.7-0.4 0-0.1 0.1-0.5t0.2-0.5q0.1-0.4-0.2-0.8-0.9-1.1-0.9-2.7 0-2.7 1.9-4.6t4.9-2q2.7 0 4.2 1.5t1.5 3.8q0 3-1.2 5.2t-3.1 2.1q-1.1 0-1.7-0.8t-0.4-1.9q0.1-0.6 0.5-1.7t0.5-1.8 0.2-1.4q0-0.9-0.5-1.5t-1.4-0.6q-1.1 0-1.9 1t-0.8 2.6q0 1.3 0.4 2.2l-1.8 7.5q-0.3 1.2-0.2 3.2-3.7-1.6-6-5t-2.3-7.6q0-3.7 1.9-6.9t5-5 6.9-1.9 6.9 1.9 5 5 1.8 6.9z\"\/><\/svg><\/span><span class=\"shariff-text\">merken<\/span>&nbsp;<\/a><\/li><li class=\"shariff-button twitter shariff-nocustomcolor\" style=\"background-color:#595959\"><a href=\"https:\/\/twitter.com\/share?url=https%3A%2F%2Fcrispycode.net%2Fde%2Fblazor-sankey-diagramm%2F&text=Ein%20einfach%20zu%20nutzendes%20Blazor%20Sankey%20Diagramm\" title=\"Bei X teilen\" aria-label=\"Bei X teilen\" role=\"button\" rel=\"noopener nofollow\" class=\"shariff-link\" style=\"; background-color:#000; color:#fff\" target=\"_blank\"><span class=\"shariff-icon\" style=\"\"><svg width=\"32px\" height=\"20px\" xmlns=\"http:\/\/www.w3.org\/2000\/svg\" viewBox=\"0 0 24 24\"><path fill=\"#000\" d=\"M14.258 10.152L23.176 0h-2.113l-7.747 8.813L7.133 0H0l9.352 13.328L0 23.973h2.113l8.176-9.309 6.531 9.309h7.133zm-2.895 3.293l-.949-1.328L2.875 1.56h3.246l6.086 8.523.945 1.328 7.91 11.078h-3.246zm0 0\"\/><\/svg><\/span><span class=\"shariff-text\">teilen<\/span>&nbsp;<\/a><\/li><\/ul><\/div>","protected":false},"excerpt":{"rendered":"<p>Entdecken Sie das Blazor Sankey Diagramm, eine Open-Source-Komponente zur Visualisierung von Prozessfl\u00fcssen und Mengen. Ideal f\u00fcr Energie, Material und Finanzen.<\/p>\n","protected":false},"author":1,"featured_media":214,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","site-sidebar-layout":"default","site-content-layout":"","ast-site-content-layout":"default","site-content-style":"default","site-sidebar-style":"default","ast-global-header-display":"","ast-banner-title-visibility":"","ast-main-header-display":"","ast-hfb-above-header-display":"","ast-hfb-below-header-display":"","ast-hfb-mobile-header-display":"","site-post-title":"","ast-breadcrumbs-content":"","ast-featured-img":"disabled","footer-sml-layout":"","ast-disable-related-posts":"","theme-transparent-header-meta":"","adv-header-id-meta":"","stick-header-meta":"","header-above-stick-meta":"","header-main-stick-meta":"","header-below-stick-meta":"","astra-migrate-meta-layouts":"default","ast-page-background-enabled":"default","ast-page-background-meta":{"desktop":{"background-color":"var(--ast-global-color-4)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"ast-content-background-meta":{"desktop":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"tablet":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""},"mobile":{"background-color":"var(--ast-global-color-5)","background-image":"","background-repeat":"repeat","background-position":"center center","background-size":"auto","background-attachment":"scroll","background-type":"","background-media":"","overlay-type":"","overlay-color":"","overlay-opacity":"","overlay-gradient":""}},"footnotes":""},"categories":[22],"tags":[],"class_list":["post-279","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-programmierung"],"uagb_featured_image_src":{"full":["https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram.webp",1200,402,false],"thumbnail":["https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram-150x150.webp",150,150,true],"medium":["https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram-300x101.webp",300,101,true],"medium_large":["https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram-768x257.webp",768,257,true],"large":["https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram-1024x343.webp",1024,343,true],"1536x1536":["https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram.webp",1200,402,false],"2048x2048":["https:\/\/crispycode.net\/wp-content\/uploads\/2023\/05\/Blazor-Sankey-Diagram.webp",1200,402,false]},"uagb_author_info":{"display_name":"Alexander Bartz","author_link":"https:\/\/crispycode.net\/de\/author\/abartz\/"},"uagb_comment_info":4,"uagb_excerpt":"Entdecken Sie das Blazor Sankey Diagramm, eine Open-Source-Komponente zur Visualisierung von Prozessfl\u00fcssen und Mengen. Ideal f\u00fcr Energie, Material und Finanzen.","_links":{"self":[{"href":"https:\/\/crispycode.net\/de\/wp-json\/wp\/v2\/posts\/279","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/crispycode.net\/de\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/crispycode.net\/de\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/crispycode.net\/de\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/crispycode.net\/de\/wp-json\/wp\/v2\/comments?post=279"}],"version-history":[{"count":5,"href":"https:\/\/crispycode.net\/de\/wp-json\/wp\/v2\/posts\/279\/revisions"}],"predecessor-version":[{"id":309,"href":"https:\/\/crispycode.net\/de\/wp-json\/wp\/v2\/posts\/279\/revisions\/309"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/crispycode.net\/de\/wp-json\/wp\/v2\/media\/214"}],"wp:attachment":[{"href":"https:\/\/crispycode.net\/de\/wp-json\/wp\/v2\/media?parent=279"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/crispycode.net\/de\/wp-json\/wp\/v2\/categories?post=279"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/crispycode.net\/de\/wp-json\/wp\/v2\/tags?post=279"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}