'Implement a D3 chart (sankey) with Angular

Trying to implement a D3 chart (sankey) to the latest version of Angular. I followed this gist, but the only thing I get is the Nodes in plain text instead of the graph.

I made a plunker with a minimum installation to reproduce the issue

Short story,

I import the libraries on my component:

import * as d3 from 'd3';
import * as d3Sankey from 'd3-sankey';

Called a DrawChart() on ngOnInit:

ngOnInit() {
      this.DrawChart();
}

Implement the DrawChart() function:

private DrawChart() {

            var svg = d3.select("#sankey"),
                width = +svg.attr("width"),
                height = +svg.attr("height");

            var formatNumber = d3.format(",.0f"),
                format = function (d: any) { return formatNumber(d) + " TWh"; },
                color = d3.scaleOrdinal(d3.schemeCategory10);

            var sankey = d3Sankey.sankey()
                .nodeWidth(15)
                .nodePadding(10)
                .extent([[1, 1], [width - 1, height - 6]]);

            var link = svg.append("g")
                .attr("class", "links")
                .attr("fill", "none")
                .attr("stroke", "#000")
                .attr("stroke-opacity", 0.2)
                .selectAll("path");

            var node = svg.append("g")
                .attr("class", "nodes")
                .attr("font-family", "sans-serif")
                .attr("font-size", 10)
                .selectAll("g");

            d3.json("../../../assets/vendors/uk2015.json", function (error, energy: any) {
                if (error) throw error;

                sankey(energy);

                link = link
                    .data(energy.links)
                    .enter().append("path")
                    .attr("d", d3Sankey.sankeyLinkHorizontal())
                    .attr("stroke-width", function (d: any) { return Math.max(1, d.width); });

                link.append("title")
                    .text(function (d: any) { return d.source.name + " → " + d.target.name + "\n" + format(d.value); });

                node = node
                    .data(energy.nodes)
                    .enter().append("g");

                node.append("rect")
                    .attr("x", function (d: any) { return d.x0; })
                    .attr("y", function (d: any) { return d.y0; })
                    .attr("height", function (d: any) { return d.y1 - d.y0; })
                    .attr("width", function (d: any) { return d.x1 - d.x0; })
                    .attr("fill", function (d: any) { return color(d.name.replace(/ .*/, "")); })
                    .attr("stroke", "#000");

                node.append("text")
                    .attr("x", function (d: any) { return d.x0 - 6; })
                    .attr("y", function (d: any) { return (d.y1 + d.y0) / 2; })
                    .attr("dy", "0.35em")
                    .attr("text-anchor", "end")
                    .text(function (d: any) { return d.name; })
                    .filter(function (d: any) { return d.x0 < width / 2; })
                    .attr("x", function (d: any) { return d.x1 + 6; })
                    .attr("text-anchor", "start");

                node.append("title")
                    .text(function (d: any) { return d.name + "\n" + format(d.value); });
            });
        }

    }

No error on console or something that will point me to the right direction.

Edit: I tried to copy paste the SVG code from the code inspector in Chrome and render it in an online SVG viewer and it works. It seems that Angular cannot render the SVG that it produces. But how I can fix it?



Solution 1:[1]

The code did not work for me as well. It didn't render, because it wasn't set as a svg-element.

Replace

var svg = d3.select("#sankey")

with

var svg = d3.select('#sankey')
    .append('svg')
    .attr('width', 1000)
    .attr('height', 500);

Your DOM will now show the svg element and it should work.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 maltemelzer