Skip to content

Commit 21c779d

Browse files
Reset forced minimum tick spacing on every calc pass
setConvert cleared ax._minDtick / ax._forceTick0 so each calc pass would start over, but the cleanup never had any effect: setConvert runs while supplyDefaults builds the new _fullLayout, where the keys do not exist yet, and relinkPrivateKeys then copies the old values back onto it. Axes.minDtick treats 0 as "forcing cancelled", so the 0 written by whichever figure was drawn first survived every later update and vetoed the forcing for every figure after it. Reacting from a scatter to a box plot lost the one-tick-per-box spacing, while newPlot of the same figure kept it. Move the reset into ax.clearCalc, the axis' own per-calc-pass reset, which doCalcdata runs for every axis before any cross-trace calc.
1 parent 21da158 commit 21c779d

3 files changed

Lines changed: 48 additions & 6 deletions

File tree

src/plots/cartesian/set_convert.js

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function isValidCategory(v) {
5858
* Creates/updates these conversion functions, and a few more utilities
5959
* like cleanRange, and makeCalcdata
6060
*
61-
* also clears ._minDtick, ._forceTick0
61+
* also creates ax.clearCalc, which clears ._minDtick, ._forceTick0
6262
*/
6363
module.exports = function setConvert(ax, fullLayout) {
6464
fullLayout = fullLayout || {};
@@ -952,6 +952,12 @@ module.exports = function setConvert(ax, fullLayout) {
952952

953953
// should skip if not category nor multicategory
954954
ax.clearCalc = function() {
955+
// for bar charts and box plots: reset forced minimum tick spacing.
956+
// this has to happen here rather than in setConvert, as the values
957+
// are relinked onto the new fullLayout after supplyDefaults runs
958+
delete ax._minDtick;
959+
delete ax._forceTick0;
960+
955961
var group = ax._matchGroup;
956962
if(group) {
957963
var categories = null;
@@ -1024,8 +1030,4 @@ module.exports = function setConvert(ax, fullLayout) {
10241030
// even though it won't be needed by this axis
10251031
ax._separators = fullLayout.separators;
10261032
ax._numFormat = locale ? locale.numberFormat : numberFormat;
1027-
1028-
// and for bar charts and box plots: reset forced minimum tick spacing
1029-
delete ax._minDtick;
1030-
delete ax._forceTick0;
10311033
};

test/jasmine/tests/axes_test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8303,6 +8303,45 @@ describe('more react tests', function() {
83038303
expect(gd._fullLayout.xaxis.range).toBeCloseToArray([-0.173, 2]);
83048304
}).then(done, done.fail);
83058305
});
8306+
8307+
it('should not carry over the forced minimum tick spacing of the previous figure', function(done) {
8308+
var layout = {width: 700, height: 400};
8309+
8310+
var scatterFig = {
8311+
data: [{y: [1, 2, 3]}],
8312+
layout: layout
8313+
};
8314+
8315+
// one box per integer position - each box forces a tick of its own
8316+
var boxFig = {
8317+
data: [{
8318+
type: 'box',
8319+
x: [1, 1, 2, 2, 3, 3],
8320+
y: [1, 2, 3, 4, 5, 6]
8321+
}],
8322+
layout: layout
8323+
};
8324+
8325+
function getXLabels() {
8326+
return gd._fullLayout.xaxis._vals.map(function(d) { return d.text; });
8327+
}
8328+
8329+
Plotly.newPlot(gd, boxFig)
8330+
.then(function() {
8331+
expect(getXLabels()).toEqual(['1', '2', '3']);
8332+
8333+
// scatter cancels the forcing for its own figure only
8334+
return Plotly.newPlot(gd, scatterFig);
8335+
})
8336+
.then(function() {
8337+
return Plotly.react(gd, boxFig);
8338+
})
8339+
.then(function() {
8340+
expect(gd._fullLayout.xaxis._minDtick).toBe(1);
8341+
expect(getXLabels()).toEqual(['1', '2', '3']);
8342+
})
8343+
.then(done, done.fail);
8344+
});
83068345
});
83078346

83088347
describe('category preservation tests on gd passed to Plotly.react()', function() {

test/jasmine/tests/plot_api_test.js

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1649,7 +1649,8 @@ describe('Test plot api', function () {
16491649
return Plotly.restyle(gd, { x0: 12.3 });
16501650
})
16511651
.then(function () {
1652-
checkTicks('x', ['12', '12.5'], 'switched to numeric');
1652+
// a single box forces one tick at its own position
1653+
checkTicks('x', ['12.3'], 'switched to numeric');
16531654
expect(gd._fullLayout.xaxis.type).toBe('linear');
16541655
})
16551656
.then(done, done.fail);

0 commit comments

Comments
 (0)