Skip to content

Commit 49b4142

Browse files
robcohenclaude
andcommitted
fix: sankey Leafs depth option now works with d3-sankey
The custom `accountingAlign` function was creating gaps in d3-sankey's internal columns array when used with Leafs (depth=0). The function returned only values 0, 1, or 2 regardless of the graph's computed maxDepth, leaving undefined slots that caused `computeNodeBreadths` to crash on `max(columns, c => c.length)`. Fix: Use default justify alignment for Leafs (depth=0) since the graph is complex with many nodes. Custom accounting alignment is still applied for depth > 0 (categories/accounts/sub-accounts). 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
1 parent ff83055 commit 49b4142

1 file changed

Lines changed: 21 additions & 10 deletions

File tree

src/sankey.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -309,26 +309,32 @@ function formatValue(value) {
309309

310310
/**
311311
* Custom node alignment for accounting Sankey
312-
* Places nodes in columns by category:
312+
* Places nodes in columns by category, scaled to the graph's depth range:
313313
* - Column 0 (LEFT): Income
314-
* - Column 1 (MIDDLE): Assets
315-
* - Column 2 (RIGHT): Expenses, Liabilities
314+
* - Column middle (CENTER): Assets
315+
* - Column max (RIGHT): Expenses, Liabilities
316+
*
317+
* The second parameter `x` is the number of columns (maxDepth + 1).
318+
* We must return values in [0, x-1] to avoid gaps in the columns array.
319+
*
316320
* @param {any} node
321+
* @param {number} x - Number of columns (maxDepth + 1)
317322
* @returns {number}
318323
*/
319-
function accountingAlign(node) {
324+
function accountingAlign(node, x) {
320325
const category = node.category;
321326
if (category === 'Income') return 0;
322-
if (category === 'Assets') return 1;
323-
return 2; // Expenses, Liabilities
327+
if (category === 'Assets') return Math.floor((x - 1) / 2);
328+
return x - 1; // Expenses, Liabilities at rightmost column
324329
}
325330

326331
/**
327332
* Render Sankey diagram
328333
* @param {HTMLElement} container
329334
* @param {{nodes: SankeyNode[], links: SankeyLink[]}} data
335+
* @param {number} depth - Account hierarchy depth (0 = Leafs, use natural graph alignment)
330336
*/
331-
function renderSankey(container, data) {
337+
function renderSankey(container, data, depth = 3) {
332338
const { nodes, links } = data;
333339

334340
if (nodes.length === 0 || links.length === 0) {
@@ -355,13 +361,12 @@ function renderSankey(container, data) {
355361
.attr('viewBox', [0, 0, width, height])
356362
.attr('class', 'sankey-svg');
357363

358-
// Create sankey generator with custom accounting alignment
364+
// Create sankey generator
359365
// linkSort by target Y position reduces link crossings (slope heuristic from d3-sankey PR #74)
360366
// iterations: scale with node count, min 6 (default), max 12 for performance
361367
// @ts-ignore - d3-sankey types are complex with generics
362368
const sankeyGenerator = sankey()
363369
.nodeId((/** @type {any} */ d) => d.fullPath)
364-
.nodeAlign(accountingAlign)
365370
.nodeWidth(8)
366371
.nodePadding(10)
367372
.iterations(Math.min(12, 6 + Math.floor(nodes.length / 5)))
@@ -374,6 +379,12 @@ function renderSankey(container, data) {
374379
[width - margin.right, height - margin.bottom],
375380
]);
376381

382+
// Use custom accounting alignment for depth > 0 (categories/accounts/sub-accounts)
383+
// For Leafs (depth=0), use default justify alignment which handles complex graphs better
384+
if (depth > 0) {
385+
sankeyGenerator.nodeAlign(accountingAlign);
386+
}
387+
377388
// Generate sankey layout
378389
// @ts-ignore - d3-sankey types are complex with generics
379390
let layoutNodes, layoutLinks;
@@ -482,7 +493,7 @@ export async function updateSankey(source, container, depth = 2) {
482493

483494
if (currentVersion !== sankeyVersion) return;
484495

485-
renderSankey(container, data);
496+
renderSankey(container, data, depth);
486497
}, 300);
487498
}
488499

0 commit comments

Comments
 (0)