Public
Edited
Dec 12, 2023
Insert cell
Insert cell
data = new Array(20).fill(0).map(() => ({
price: Math.floor(Math.random() * (1000000 - 500000 + 1)) + 500000,
loanorigid: ['1234', '5678', '9012', '3456', '78920', '212223'][Math.floor(Math.random() * ['1234', '5678', '9012', '3456', '78920', '212223'].length)]
}))
Insert cell
chart = {
const sankeyData = {
nodes: [],
links: []
};

// Common source for all flows
sankeyData.nodes.push({ name: "Total Amount" });

data.forEach(d => {
// Check if the node already exists in the nodes array
let targetNode = sankeyData.nodes.find(node => node.name === d.loanorigid);

// If the node does not exist, add it
if (!targetNode) {
targetNode = { name: d.loanorigid };
sankeyData.nodes.push(targetNode);
}

// Find the index of the node in the nodes array
const targetIndex = sankeyData.nodes.indexOf(targetNode);

// Add a link from the source to this target node
sankeyData.links.push({
source: 0, // Index of "Total Amount" node
target: targetIndex,
value: d.price
});
});


// Make sure sankeyData is populated correctly
console.log("Sankey Data:", sankeyData);
const color = d3.scaleOrdinal(d3.schemeCategory10);

// Set up the dimensions and properties for the Sankey diagram
const width = 600, height = 400;

// Create SVG element
const svg = d3.create("svg")
.attr("width", width)
.attr("height", height);

// Set up the Sankey generator
const sankey = d3Sankey.sankey()
.nodeWidth(15)
.nodePadding(10)
.extent([[1, 1], [width - 1, height - 5]])
.size([width, height]);

// Compute the Sankey diagram
const sankeyGraph = sankey(sankeyData);

// Draw the links (the paths between nodes)
svg.append("g")
.selectAll("path")
.data(sankeyGraph.links)
.join("path")
.attr("d", d3Sankey.sankeyLinkHorizontal())
.style("fill", "none")
.style("stroke", d => color(d.target.name))
.style("stroke-opacity", 0.5)
.style("stroke-width", d => Math.max(1, d.width));

// Draw the nodes (the rectangles)
svg.append("g")
.selectAll("rect")
.data(sankeyGraph.nodes)
.join("rect")
.attr("x", d => d.x0)
.attr("y", d => d.y0)
.attr("height", d => d.y1 - d.y0)
.attr("width", sankey.nodeWidth())
.style("fill", d => color(d.name));

const formatCurrency = d3.format("$,.2f");
// Add labels to the nodes
svg.append("g")
.selectAll("text")
.data(sankeyGraph.nodes)
.join("text")
.attr("x", d => ((d.x0 + d.x1) / 2) - 100)
.attr("y", d => (d.y0 + d.y1) / 2)
.text(d => `${d.name} Total: ${formatCurrency(d.value)}`)
.attr("font-size", "13px")
.attr("text-anchor", "middle")
.attr("alignment-baseline", "middle")
.style("fill", "black");

return svg.node();
}
Insert cell
d3Sankey = require('d3-sankey')
Insert cell

Purpose-built for displays of data

Observable is your go-to platform for exploring data and creating expressive data visualizations. Use reactive JavaScript notebooks for prototyping and a collaborative canvas for visual data exploration and dashboard creation.
Learn more