diff --git a/draftlogs/7507_fix.md b/draftlogs/7507_fix.md new file mode 100644 index 00000000000..3ac7d1b5cd7 --- /dev/null +++ b/draftlogs/7507_fix.md @@ -0,0 +1 @@ +Fix `histogram` autobin size for single-point traces in `overlay` mode on data updates via `Plotly.react` [[#7507](https://github.com/plotly/plotly.js/pull/7507)] diff --git a/src/traces/histogram/calc.js b/src/traces/histogram/calc.js index e705ddd36fa..7268e3eaab2 100644 --- a/src/traces/histogram/calc.js +++ b/src/traces/histogram/calc.js @@ -308,10 +308,11 @@ function calcAllAutoBins(gd, trace, pa, mainData, _overlayEdgeCase) { // Edge case: single-valued histogram overlaying others // Use them all together to calculate the bin size for the single-valued one - // Don't re-calculate bin width if user manually specified it (checing in bingroup=='' or xbins is defined) + // Don't re-calculate bin width if user manually specified it + // Check if bingroup or bin size is defined if(isOverlay && !Registry.traceIs(trace, '2dMap') && newBinSpec._dataSpan === 0 && pa.type !== 'category' && pa.type !== 'multicategory' && - trace.bingroup === '' && (typeof trace.xbins === 'undefined')) { + trace.bingroup === '' && trace._input?.[binAttr]?.size === undefined) { // Several single-valued histograms! Stop infinite recursion, // just return an extra flag that tells handleSingleValueOverlays // to sort out this trace too diff --git a/test/jasmine/tests/histogram_test.js b/test/jasmine/tests/histogram_test.js index d6136772b5f..08bf9082b5d 100644 --- a/test/jasmine/tests/histogram_test.js +++ b/test/jasmine/tests/histogram_test.js @@ -1335,6 +1335,43 @@ describe('Test histogram', function() { }) .then(done, done.fail); }); + + it('should correctly recalculate autobin size for single-value overlays on Plotly.react', function(done) { + var initialData = [ + {x: ['1457'], type: 'histogram'}, + {x: ['820'], type: 'histogram'}, + {x: ['720'], type: 'histogram'} + ]; + + var layout = { + barmode: 'overlay' + }; + + Plotly.newPlot(gd, initialData, layout) + .then(function() { + // minDiff = 820 - 720 = 100 + console.log("gd._fullData=", gd._fullData); + expect(gd._fullData[0].xbins.size).toBe(100); + expect(gd._fullData[1].xbins.size).toBe(100); + expect(gd._fullData[2].xbins.size).toBe(100); + + // Use a new trace data object + var newData = [ + {x: ['1400'], type: 'histogram'}, + {x: ['800'], type: 'histogram'}, + {x: ['600'], type: 'histogram'} + ]; + + return Plotly.react(gd, newData, layout); + }) + .then(function() { + // minDiff = 800 - 600 = 200. + expect(gd._fullData[0].xbins.size).toBe(200); + expect(gd._fullData[1].xbins.size).toBe(200); + expect(gd._fullData[2].xbins.size).toBe(200); + }) + .then(done, done.fail); + }); }); });