setup = {
const margin = { top: 10, right: 250, bottom: 10, left: 300 }
const leafSet = new Set();
graph.links.map(d => leafSet.add(d.source));
const nodeIds = Array.from(leafSet);
const parentSet = new Set();
graph.links.map(d => parentSet.add(d.target));
const parentIds = Array.from(parentSet);
const height = nodeIds.length * 10
const width = 200
const y1 = d3
.scaleBand()
.domain(parentIds)
.range([0, height]),
y2 = d3
.scaleBand()
.domain(nodeIds)
.range([0, height]),
axis1 = d3.axisLeft(y1)
.tickFormat(function(d) {
return graph.nodes[d].name;
}),
axis2 = d3.axisRight(y2)
.tickFormat(function(d) {
return graph.nodes[d].name;
}),
link = d3.linkHorizontal();
const svg = d3
.create("svg")
.attr("width", width + margin.left + margin.right)
.attr("height", height + margin.top + margin.bottom);
const g = svg
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
const gAxisLeft = g
.append("g")
.call(axis1);
const gAxisRight = g
.append("g")
.attr("transform", "translate(" + width + ",0)")
.call(axis2);
const matrix = graph.links
.flatMap(({ source, target, value }) => [
[source, target, value]
]);
const edges = g
.append("g")
.selectAll("path")
.data(matrix)
.join("path")
.attr("d", d => (link({
source: [0, y1(d[1]) + y1.bandwidth()/2],
target: [width, y2(d[0]) + y2.bandwidth()/2]
})))
.attr("fill","none")
.attr("stroke","black")
let prev;
update(graph.nodes.map(d => +d.id));
function update(permutation) {
y1.domain(permutation.filter(function(d) {return parentSet.has(d)}));
y2.domain(permutation.filter(function(d) {return leafSet.has(d)}));
const duration = 1000
gAxisLeft
.transition()
.duration(duration)
.call(axis1)
gAxisRight
.transition()
.duration(duration)
.call(axis2)
edges
.transition()
.duration(duration)
.attr("d", d => (link({
source: [0, y1(d[1]) + y1.bandwidth()/2],
target: [width, y2(d[0]) + y2.bandwidth()/2]
})))
prev = permutation;
return permutation;
}
return Object.assign(svg.node(), { update });
}