'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 |
