In my project I draw a sankey graph with d3.js
version 6.2.0 and d3-sankey
version 0.12.3. The result is in the following screenshot.
In the source file I have some groups
{
"nodes": [
{
"group_nodes": "1st line",
"name": "CL",
"id": 0
},
{
"group_nodes": "2nd line",
"name": "COMT, CL, DA",
"id": 9
},
{
"group_nodes": "3rd line",
"name": "COMT",
"id": 39
}
],
"links": [
]
}
What I want to achieve is to align each group in one column. For example, all group 1 on the left, group 2 in the middle of the graph and the group 3 on the right.
function DrawSankey() {
d3.json("../data.json").then(function (sankeydata) {
graph = sankey(sankeydata);
// add in the links
var link = svg.append('g').selectAll('.link')
.data(graph.links)
.enter().append('path')
.attr('class', 'link')
.attr("d", d3.sankeyLinkHorizontal())
.style('stroke-width', 5) // d => Math.max(10, d.dy)
.style('fill', 'none')
.style('stroke-opacity', 0.4)
.sort((a, b) => b.dy - a.dy)
.on('mouseover', function () {
d3.select(this).style('stroke-opacity', 0.6);
})
.on('mouseout', function () {
d3.select(this).style('stroke-opacity', 0.4);
});
// add the link titles
link.append("title")
.text(function (d) {
return d.source.name + " → " +
d.target.name + "\n" + format(d.value);
});
// add in the nodes
var node = svg.append("g").selectAll(".node")
.data(graph.nodes)
.enter().append("g")
.attr("class", "node")
.attr("transform", function (d) {
return "translate(" + d.x + "," + d.y + ")";
})
.call(d3.drag()
.subject(function (d) {
return d;
})
.on('start', function (event, d) {
this.parentNode.appendChild(this)
})
.on("drag", dragmove));
// add the rectangles for the nodes
node.append("rect")
.attr("x", function (d) { return d.x0; })
.attr("y", function (d) { return d.y0; })
.attr("height", function (d) { return d.y1 - d.y0; })
.attr("width", sankey.nodeWidth())
.style("fill", function (d) {
return d.color = color(d.name.replace(/ .*/, ""));
})
.attr("stroke", "#000")
.append("title")
.text(function (d) {
return d.name + "\n" + format(d.value);
});
// add in the title for the nodes
node.append("text")
.attr("x", function (d) { return d.x0 - 6; })
.attr("y", function (d) { return (d.y1 + d.y0) / 2; })
.attr("dy", "0.35em")
.attr("text-anchor", "end")
.text(function (d) { return d.name; })
.filter(function (d) { return d.x0 < width / 2; })
.attr("x", function (d) { return d.x1 + 6; })
.attr("text-anchor", "start");
// add gradient to links
link.style('stroke', (d, i) => {
// make unique gradient ids
const gradientID = `gradient${i}`;
const startColor = d.source.color;
const stopColor = d.target.color;
console.log('startColor', startColor);
console.log('stopColor', stopColor);
const linearGradient = defs.append('linearGradient')
.attr('id', gradientID);
linearGradient.selectAll('stop')
.data([
{ offset: '25%', color: startColor },
{ offset: '75%', color: stopColor }
])
.enter().append('stop')
.attr('offset', d => {
console.log('d.offset', d.offset);
return d.offset;
})
.attr('stop-color', d => {
console.log('d.color', d.color);
return d.color;
});
return `url(#${gradientID})`;
})
})
function dragmove(d) {
d3.select(this)
.attr("transform",
"translate("
+ d.x + ","
+ (d.y = Math.max(
0, Math.min(height - d.dy, event.y))
) + ")");
sankey.update(graph);
}
}
Also, I have an issue when I drag a bar. As you can see in the following screenshot, when I move a bar, it isn't connected with the lines and the bar disappeared.