From bf955679d25e96abd9cb10252208de1d989c3b41 Mon Sep 17 00:00:00 2001 From: kyosuke Date: Sat, 6 Jun 2026 05:54:15 +0900 Subject: [PATCH 1/2] Fix explicit node positions in fixed-arrangement Sankey --- src/traces/sankey/render.js | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/src/traces/sankey/render.js b/src/traces/sankey/render.js index a07d18a9c9e..b528a5f5b96 100644 --- a/src/traces/sankey/render.js +++ b/src/traces/sankey/render.js @@ -244,15 +244,23 @@ function sankeyModel(layout, d, traceIndex) { // Force node position if(trace.node.x.length && trace.node.y.length) { - for(i = 0; i < Math.min(trace.node.x.length, trace.node.y.length, graph.nodes.length); i++) { - if(trace.node.x[i] && trace.node.y[i]) { - var pos = [trace.node.x[i] * width, trace.node.y[i] * height]; - graph.nodes[i].x0 = pos[0] - nodeThickness / 2; - graph.nodes[i].x1 = pos[0] + nodeThickness / 2; - - var nodeHeight = graph.nodes[i].y1 - graph.nodes[i].y0; - graph.nodes[i].y0 = pos[1] - nodeHeight / 2; - graph.nodes[i].y1 = pos[1] + nodeHeight / 2; + // graph.nodes omits unlinked nodes and may have transient group + // children unshifted to its front, so its order does not match + // trace.node.x/y. Index the explicit positions by each node's + // original pointNumber rather than by array position. + for(i = 0; i < graph.nodes.length; i++) { + var forcedNode = graph.nodes[i]; + if(forcedNode.partOfGroup) continue; + + var p = forcedNode.pointNumber; + if(trace.node.x[p] && trace.node.y[p]) { + var pos = [trace.node.x[p] * width, trace.node.y[p] * height]; + forcedNode.x0 = pos[0] - nodeThickness / 2; + forcedNode.x1 = pos[0] + nodeThickness / 2; + + var nodeHeight = forcedNode.y1 - forcedNode.y0; + forcedNode.y0 = pos[1] - nodeHeight / 2; + forcedNode.y1 = pos[1] + nodeHeight / 2; } } if(trace.arrangement === 'snap') { From 86084f9a39bc2e04649fcac4a702db75a29c4c5c Mon Sep 17 00:00:00 2001 From: kyosuke Date: Sat, 6 Jun 2026 05:56:54 +0900 Subject: [PATCH 2/2] Add draftlog for #7826 --- draftlogs/7826_fix.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 draftlogs/7826_fix.md diff --git a/draftlogs/7826_fix.md b/draftlogs/7826_fix.md new file mode 100644 index 00000000000..4290a25a1ef --- /dev/null +++ b/draftlogs/7826_fix.md @@ -0,0 +1 @@ +- Respect explicit `node.x`/`node.y` positions in Sankey traces that contain unlinked or grouped nodes, by indexing the forced positions by each node's `pointNumber` instead of its array position [[#7826](https://github.com/plotly/plotly.js/pull/7826)]