parallelSet = {
const svg = d3.create("svg").attr("viewBox", [0, 0, width, height]);
var color = d3.scaleOrdinal(d3.schemePastel2);
const sankey = d3.sankey()
.size([width, height - 10])
.nodeWidth(5)
.nodePadding(20)
.nodeSort(null)
.linkSort(null);
let key_array = [];
let key_index = -1;
for (let i = 0; i < category_array.length; i++) {
if(category_array[i] == "value"){
console.log("Found value and cutting it off for visualization - " + i + ". position!");
continue;
}else{
key_index++;
}
key_array[key_index] = category_array[i];
}
const {nodes, links} = sankey(graph(key_array));
var node = svg.append("g")
.selectAll("rect")
.data(nodes).enter()
.append("rect")
.attr("x", d => d.x0)
.attr("y", d => d.y0)
.attr("height", d => d.y1 - d.y0)
.attr("width", d => d.x1 - d.x0); // sankey.nodeWidth()
var link = svg.append("g")
.attr("fill", "none")
.selectAll("g")
.data(links).enter()
.append("path")
.attr("d", d3.sankeyLinkHorizontal())
.attr("stroke", d => color(d.names[0])) // color of first attribute (left to right)
.style("stroke-width", d => Math.max(1, d.width))
// specifies how an element’s content should blend with its background
.style("mix-blend-mode", "multiply"/*"overlay"*/)
// shows specific relation value in mouse-window
.append("title")
.text(d => d.names.join(" -> ")+ ": " + d.value)
// relationship of 2 attribute axis
// .text(d => d.source.name + " -> " + d.target.name + ": " + d.value);
var node_text = svg.append("g")
// .style("font", "12px sans-serif")
.attr("font-family", "sans-serif")
.attr("font-size", 12)
.selectAll("text")
.data(nodes).enter()
.append("text")
.attr("x", d => d.x0 < width / 2 ? d.x1 + 6 : d.x0 - 6)
.attr("y", d => (d.y1 + d.y0) / 2)
.attr("text-anchor", "end")
.text(d => d.name + ": " + d.value)
.filter(d => d.x0 < width / 2)
.attr("text-anchor", "start");
return svg.node();
}
/*
sources:
https://observablehq.com/@d3/parallel-sets?collection=@d3/d3-sankey
https://jarrettmeyer.com/2018/05/31/creating-a-d3-sankey-graph
https://observablehq.com/@aaronkyle/sankey-diagram-d3v5
*/