From 5dc104e640dc80a7a40c0f60fd45c97b7aada666 Mon Sep 17 00:00:00 2001 From: adimalkar Date: Sat, 31 Oct 2026 23:18:03 -0400 Subject: [PATCH 1/2] Apply sankey node positions of 0 instead of placing the node automatically The force-node-position loop tested node.x and node.y for truthiness, so a coordinate of 0 counted as missing and the node was positioned by the layout instead. Test for null and undefined only. --- draftlogs/PRNUM_fix.md | 1 + src/traces/sankey/render.js | 2 +- test/jasmine/tests/sankey_test.js | 14 ++++++++++++++ 3 files changed, 16 insertions(+), 1 deletion(-) create mode 100644 draftlogs/PRNUM_fix.md diff --git a/draftlogs/PRNUM_fix.md b/draftlogs/PRNUM_fix.md new file mode 100644 index 00000000000..db996e77dba --- /dev/null +++ b/draftlogs/PRNUM_fix.md @@ -0,0 +1 @@ + - Position a sankey node at `node.x` or `node.y` of `0` instead of placing it automatically [[#PRNUM](https://github.com/plotly/plotly.js/pull/PRNUM)] diff --git a/src/traces/sankey/render.js b/src/traces/sankey/render.js index 30a7df024d1..372ddbfc23a 100644 --- a/src/traces/sankey/render.js +++ b/src/traces/sankey/render.js @@ -270,7 +270,7 @@ function sankeyModel(layout, d, traceIndex) { if(forcedNode.partOfGroup) continue; var p = forcedNode.pointNumber; - if (trace.node.x[p] && trace.node.y[p]) { + if (trace.node.x[p] != null && trace.node.y[p] != null) { var pos = [trace.node.x[p] * width, trace.node.y[p] * height]; forcedNode.x0 = pos[0] - nodeThickness / 2; forcedNode.x1 = pos[0] + nodeThickness / 2; diff --git a/test/jasmine/tests/sankey_test.js b/test/jasmine/tests/sankey_test.js index 9220f95d7c3..6c690e5a4e8 100644 --- a/test/jasmine/tests/sankey_test.js +++ b/test/jasmine/tests/sankey_test.js @@ -762,6 +762,20 @@ describe('sankey tests', function () { .then(done, done.fail); }); + it('applies a position of 0 like any other position', (done) => { + const fig = makeFixedMock(); + // A falsy test used to treat 0 as a missing position + fig.data[0].node.x[0] = 0; + fig.data[0].node.y[0] = 0; + fig.data[0].node.y[4] = 0; + + Plotly.newPlot(gd, fig) + .then(() => { + assertPositions(fig.data[0], getCentersByIndex(), [0, 2, 3, 4], 'zero'); + }) + .then(done, done.fail); + }); + it('keeps the positions of the other nodes after a drag when a node is unlinked', (done) => { const fig = makeFixedMock(); fig.data[0].arrangement = 'freeform'; From f4af1e421350706e7261484b7937e6a3bdff0d47 Mon Sep 17 00:00:00 2001 From: adimalkar Date: Sat, 31 Oct 2026 23:18:25 -0400 Subject: [PATCH 2/2] Name the draftlog for #8158 --- draftlogs/8158_fix.md | 1 + draftlogs/PRNUM_fix.md | 1 - 2 files changed, 1 insertion(+), 1 deletion(-) create mode 100644 draftlogs/8158_fix.md delete mode 100644 draftlogs/PRNUM_fix.md diff --git a/draftlogs/8158_fix.md b/draftlogs/8158_fix.md new file mode 100644 index 00000000000..f272bd615f2 --- /dev/null +++ b/draftlogs/8158_fix.md @@ -0,0 +1 @@ + - Position a sankey node at `node.x` or `node.y` of `0` instead of placing it automatically [[#8158](https://github.com/plotly/plotly.js/pull/8158)] diff --git a/draftlogs/PRNUM_fix.md b/draftlogs/PRNUM_fix.md deleted file mode 100644 index db996e77dba..00000000000 --- a/draftlogs/PRNUM_fix.md +++ /dev/null @@ -1 +0,0 @@ - - Position a sankey node at `node.x` or `node.y` of `0` instead of placing it automatically [[#PRNUM](https://github.com/plotly/plotly.js/pull/PRNUM)]