From ff311c5031105a688fa54810ec65481ae3f17536 Mon Sep 17 00:00:00 2001 From: capy-zhiao Date: Thu, 15 Oct 2026 01:58:09 -0400 Subject: [PATCH 1/2] fix #8117 - don't reuse stale zmin/zmax for autocontour when coloring is 'none' With `contours.coloring: 'none'` the colorscale attributes are not coerced, so `zauto` is undefined on the full trace. After `Plotly.react`, `relinkPrivateKeys` + `Colorscale.crossTraceDefaults` put the previous `_zmin`/`_zmax` back onto `zmin`/`zmax`, and `setContours` used them because `trace.zauto` was falsy. Treat an undefined `zauto` as auto, as `Colorscale.calc` already does. --- src/traces/contour/set_contours.js | 8 ++++++-- test/jasmine/tests/contour_test.js | 29 +++++++++++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/src/traces/contour/set_contours.js b/src/traces/contour/set_contours.js index 77b8879f245..0724d67b0f9 100644 --- a/src/traces/contour/set_contours.js +++ b/src/traces/contour/set_contours.js @@ -12,10 +12,14 @@ module.exports = function setContours(trace, vals) { // these values here are meant to remain "per-trace" for now var zmin = trace.zmin; var zmax = trace.zmax; - if(trace.zauto || zmin === undefined) { + // `zauto` is only coerced when the trace has a colorscale (i.e. not for + // `contours.coloring: 'none'`). Treat an undefined `zauto` as auto, like + // Colorscale.calc does, so that we never reuse the zmin/zmax relinked + // from a previous full trace after `Plotly.react` (see #8117). + if(trace.zauto !== false || zmin === undefined) { zmin = Lib.aggNums(Math.min, null, vals); } - if(trace.zauto || zmax === undefined) { + if(trace.zauto !== false || zmax === undefined) { zmax = Lib.aggNums(Math.max, null, vals); } diff --git a/test/jasmine/tests/contour_test.js b/test/jasmine/tests/contour_test.js index ae098a30702..15bb205acee 100644 --- a/test/jasmine/tests/contour_test.js +++ b/test/jasmine/tests/contour_test.js @@ -622,6 +622,35 @@ describe('contour plotting and editing', function() { .then(done, done.fail); }); + it('should recompute autocontour levels from the new z on react when coloring is *none*', function(done) { + // https://github.com/plotly/plotly.js/issues/8117 + // with contours.coloring 'none' the colorscale attributes are not coerced, + // so setContours must not reuse the zmin/zmax relinked from the previous full trace + function _trace(z) { + return {type: 'contour', z: z, contours: {coloring: 'none'}}; + } + + function _assertLevels(msg, start, end, size) { + var contours = gd._fullData[0].contours; + expect(contours.start).toBe(start, msg + ' start'); + expect(contours.end).toBe(end, msg + ' end'); + expect(contours.size).toBe(size, msg + ' size'); + expect(gd.querySelectorAll('.contourlevel path').length).toBeGreaterThan(0, msg + ' no contour lines drawn'); + } + + Plotly.newPlot(gd, [_trace([[1, 2, 3], [4, 5, 6], [7, 8, 9]])]) + .then(function() { + _assertLevels('initial', 2, 8, 1); + + // new trace object and new z array, with a completely different range + return Plotly.react(gd, [_trace([[4100, 4200, 4300], [4400, 4500, 4600], [4700, 4800, 4900]])]); + }) + .then(function() { + _assertLevels('after react', 4200, 4800, 100); + }) + .then(done, done.fail); + }); + it('keeps the correct ordering after hide and show', function(done) { function getIndices() { var out = []; From 2c74afe4e4776416a7dc7c5226e439a922c97404 Mon Sep 17 00:00:00 2001 From: capy-zhiao Date: Thu, 15 Oct 2026 02:00:56 -0400 Subject: [PATCH 2/2] add draftlog for #8122 --- draftlogs/8122_fix.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 draftlogs/8122_fix.md diff --git a/draftlogs/8122_fix.md b/draftlogs/8122_fix.md new file mode 100644 index 00000000000..e20d32ebbfc --- /dev/null +++ b/draftlogs/8122_fix.md @@ -0,0 +1 @@ +- Fix contour levels being computed from stale `zmin`/`zmax` after `Plotly.react` when `contours.coloring` is `none` [[#8122](https://github.com/plotly/plotly.js/pull/8122)]