{
const { sankey, sankeyLinkHorizontal } = d3;
const nodes = Array.from(new Set(survivors_data.flatMap(d => [d.source, d.target])))
.map(name => ({ name }));
const nodeMap = new Map(nodes.map((d, i) => [d.name, i]));
const links = survivors_data.map(d => ({
source: nodeMap.get(d.source),
target: nodeMap.get(d.target),
value: d.value
}));
const sankeyGenerator = sankey()
.nodeWidth(85)
.nodePadding(10)
.extent([[20, 1], [850, 400]]);
const { nodes: layoutNodes, links: layoutLinks } = sankeyGenerator({
nodes: nodes.map(d => Object.assign({}, d)),
links: links.map(d => Object.assign({}, d))
});
const svg = d3.create("svg")
.attr("width", 900)
.attr("height", 420);
svg.append("g")
.selectAll("path")
.data(layoutLinks)
.join("path")
.attr("d", sankeyLinkHorizontal())
.attr("stroke", "steelblue")
.attr("stroke-width", d => d.width)
.attr("fill", "none")
.attr("opacity", 0.6);
svg.append("g")
.selectAll("rect")
.data(layoutNodes)
.join("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)
.attr("fill", "#a9cee8");
svg.append("g")
.selectAll("text")
.data(layoutNodes)
.join("text")
.attr("fill", "#313a54")
.attr("x", d => d.x0)
.attr("y", d => (d.y1 + d.y0) / 2)
.attr("text-anchor", "start")
.attr("dy", "0.35em")
.text(d => d.name);
return svg.node();
}