From bcaa904f6f02fae5814c0d68dbf855bfe098d1a9 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Wed, 4 Oct 2023 11:26:40 -0400 Subject: [PATCH 1/4] add a function to handle range defaults --- src/plots/cartesian/axis_defaults.js | 35 ++-------------------- src/plots/cartesian/range_defaults.js | 42 +++++++++++++++++++++++++++ 2 files changed, 44 insertions(+), 33 deletions(-) create mode 100644 src/plots/cartesian/range_defaults.js diff --git a/src/plots/cartesian/axis_defaults.js b/src/plots/cartesian/axis_defaults.js index fbfcbe41233..886f4235c03 100644 --- a/src/plots/cartesian/axis_defaults.js +++ b/src/plots/cartesian/axis_defaults.js @@ -15,7 +15,7 @@ var handleTickLabelDefaults = require('./tick_label_defaults'); var handlePrefixSuffixDefaults = require('./prefix_suffix_defaults'); var handleCategoryOrderDefaults = require('./category_order_defaults'); var handleLineGridDefaults = require('./line_grid_defaults'); -var handleAutorangeOptionsDefaults = require('./autorange_options_defaults'); +var handleRangeDefaults = require('./range_defaults'); var setConvert = require('./set_convert'); var DAY_OF_WEEK = require('./constants').WEEKDAY_PATTERN; @@ -92,38 +92,7 @@ module.exports = function handleAxisDefaults(containerIn, containerOut, coerce, setConvert(containerOut, layoutOut); - coerce('minallowed'); - coerce('maxallowed'); - var range = coerce('range'); - var autorangeDflt = containerOut.getAutorangeDflt(range, options); - var autorange = coerce('autorange', autorangeDflt); - - var shouldAutorange; - - // validate range and set autorange true for invalid partial ranges - if(range && ( - (range[0] === null && range[1] === null) || - ((range[0] === null || range[1] === null) && (autorange === 'reversed' || autorange === true)) || - (range[0] !== null && (autorange === 'min' || autorange === 'max reversed')) || - (range[1] !== null && (autorange === 'max' || autorange === 'min reversed')) - )) { - range = undefined; - delete containerOut.range; - containerOut.autorange = true; - shouldAutorange = true; - } - - if(!shouldAutorange) { - autorangeDflt = containerOut.getAutorangeDflt(range, options); - autorange = coerce('autorange', autorangeDflt); - } - - if(autorange) { - handleAutorangeOptionsDefaults(coerce, autorange, range); - if(axType === 'linear' || axType === '-') coerce('rangemode'); - } - - containerOut.cleanRange(); + handleRangeDefaults(containerIn, containerOut, coerce, options); handleCategoryOrderDefaults(containerIn, containerOut, coerce, options); diff --git a/src/plots/cartesian/range_defaults.js b/src/plots/cartesian/range_defaults.js new file mode 100644 index 00000000000..eefb9c19703 --- /dev/null +++ b/src/plots/cartesian/range_defaults.js @@ -0,0 +1,42 @@ +'use strict'; + +var handleAutorangeOptionsDefaults = require('./autorange_options_defaults'); + +module.exports = function handleRangeDefaults(containerIn, containerOut, coerce, options) { + var axTemplate = containerOut._template || {}; + var axType = containerOut.type || axTemplate.type || '-'; + + coerce('minallowed'); + coerce('maxallowed'); + + var range = coerce('range'); + var autorangeDflt = containerOut.getAutorangeDflt(range, options); + var autorange = coerce('autorange', autorangeDflt); + + var shouldAutorange; + + // validate range and set autorange true for invalid partial ranges + if(range && ( + (range[0] === null && range[1] === null) || + ((range[0] === null || range[1] === null) && (autorange === 'reversed' || autorange === true)) || + (range[0] !== null && (autorange === 'min' || autorange === 'max reversed')) || + (range[1] !== null && (autorange === 'max' || autorange === 'min reversed')) + )) { + range = undefined; + delete containerOut.range; + containerOut.autorange = true; + shouldAutorange = true; + } + + if(!shouldAutorange) { + autorangeDflt = containerOut.getAutorangeDflt(range, options); + autorange = coerce('autorange', autorangeDflt); + } + + if(autorange) { + handleAutorangeOptionsDefaults(coerce, autorange, range); + if(axType === 'linear' || axType === '-') coerce('rangemode'); + } + + containerOut.cleanRange(); +}; From cf059c26670aed52cb0b8151de996ffa440164a7 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Wed, 4 Oct 2023 12:00:34 -0400 Subject: [PATCH 2/4] fix issue 6742 interactions of partial ranges affecting other subplots --- src/plot_api/plot_api.js | 30 +++++++++++++----------------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/src/plot_api/plot_api.js b/src/plot_api/plot_api.js index b41bbce29f0..7e50588c651 100644 --- a/src/plot_api/plot_api.js +++ b/src/plot_api/plot_api.js @@ -15,6 +15,9 @@ var PlotSchema = require('./plot_schema'); var Plots = require('../plots/plots'); var Axes = require('../plots/cartesian/axes'); +var handleRangeDefaults = require('../plots/cartesian/range_defaults'); + +var cartesianLayoutAttributes = require('../plots/cartesian/layout_attributes'); var Drawing = require('../components/drawing'); var Color = require('../components/color'); var initInteractions = require('../plots/cartesian/graph_interact').initInteractions; @@ -1838,26 +1841,19 @@ function axRangeSupplyDefaultsByPass(gd, flags, specs) { if(k !== 'axrange' && flags[k]) return false; } + var axIn, axOut; + var coerce = function(attr, dflt) { + return Lib.coerce(axIn, axOut, cartesianLayoutAttributes, attr, dflt); + }; + + var options = {}; // passing empty options for now! + for(var axId in specs.rangesAltered) { var axName = Axes.id2name(axId); - var axIn = gd.layout[axName]; - var axOut = fullLayout[axName]; - axOut.autorange = axIn.autorange; + axIn = gd.layout[axName]; + axOut = fullLayout[axName]; - var r0 = axOut._rangeInitial0; - var r1 = axOut._rangeInitial1; - // partial range needs supplyDefaults - if( - (r0 === undefined && r1 !== undefined) || - (r0 !== undefined && r1 === undefined) - ) { - return false; - } - - if(axIn.range) { - axOut.range = axIn.range.slice(); - } - axOut.cleanRange(); + handleRangeDefaults(axIn, axOut, coerce, options); if(axOut._matchGroup) { for(var axId2 in axOut._matchGroup) { From 95b8edc80499b4b7134ff9808ae42f948017a039 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Wed, 4 Oct 2023 13:07:58 -0400 Subject: [PATCH 3/4] add test --- test/jasmine/tests/axes_test.js | 97 +++++++++++++++++++++++++++++++++ 1 file changed, 97 insertions(+) diff --git a/test/jasmine/tests/axes_test.js b/test/jasmine/tests/axes_test.js index 8b65344e5bb..d0a0e2ffc5d 100644 --- a/test/jasmine/tests/axes_test.js +++ b/test/jasmine/tests/axes_test.js @@ -1581,6 +1581,103 @@ describe('Test axes', function() { .then(done, done.fail); }); + it('can relayout one partial range without affecting other subplots', function(done) { + var rangeX2; + var rangeX3; + var rangeX4; + var autorangeX2; + var autorangeX3; + var autorangeX4; + + Plotly.newPlot(gd, { + data: [ + { + xaxis: 'x', + yaxis: 'y', + y: [1000, 10, 100, 1], + }, + { + xaxis: 'x2', + yaxis: 'y2', + y: [1000, 10, 100, 1], + }, + { + xaxis: 'x3', + yaxis: 'y3', + y: [1000, 10, 100, 1], + }, + { + xaxis: 'x4', + yaxis: 'y4', + y: [1000, 10, 100, 1], + }, + ], + layout: { + xaxis: { + range: [-1, null], + anchor: 'y', + domain: [0, 0.45], + }, + yaxis: { + anchor: 'x', + domain: [0, 0.45], + side: 'right', + }, + xaxis2: { + range: [null, 4], + anchor: 'y2', + domain: [0, 0.45], + }, + yaxis2: { + anchor: 'x2', + domain: [0.55, 1], + side: 'left', + }, + xaxis3: { + range: [null, -1], + autorange: 'max reversed', + anchor: 'y3', + domain: [0.55, 1], + }, + yaxis3: { + anchor: 'x3', + domain: [0, 0.45], + side: 'left', + }, + xaxis4: { + range: [4, null], + autorange: 'min reversed', + anchor: 'y4', + domain: [0.55, 1], + }, + yaxis4: { + anchor: 'x4', + domain: [0.55, 1], + side: 'right', + } + } + }).then(function() { + rangeX2 = gd._fullLayout.xaxis2.range.slice(); + rangeX3 = gd._fullLayout.xaxis3.range.slice(); + rangeX4 = gd._fullLayout.xaxis4.range.slice(); + + autorangeX2 = gd._fullLayout.xaxis2.autorange; + autorangeX3 = gd._fullLayout.xaxis3.autorange; + autorangeX4 = gd._fullLayout.xaxis4.autorange; + + return Plotly.relayout(gd, 'xaxis.range', [1, 2]); + }).then(function() { + expect(gd._fullLayout.xaxis2.range).toEqual(rangeX2); + expect(gd._fullLayout.xaxis3.range).toEqual(rangeX3); + expect(gd._fullLayout.xaxis4.range).toEqual(rangeX4); + + expect(gd._fullLayout.xaxis2.autorange).toEqual(autorangeX2); + expect(gd._fullLayout.xaxis3.autorange).toEqual(autorangeX3); + expect(gd._fullLayout.xaxis4.autorange).toEqual(autorangeX4); + }) + .then(done, done.fail); + }); + it('should make room for the inside labels of the counter axes', function(done) { Plotly.newPlot(gd, { data: [{ From 3cc3c4295f1cea8ce00a2377fd5c8047bd619166 Mon Sep 17 00:00:00 2001 From: Mojtaba Samimi Date: Wed, 4 Oct 2023 13:23:51 -0400 Subject: [PATCH 4/4] draftlog --- draftlogs/6743_fix.md | 1 + 1 file changed, 1 insertion(+) create mode 100644 draftlogs/6743_fix.md diff --git a/draftlogs/6743_fix.md b/draftlogs/6743_fix.md new file mode 100644 index 00000000000..ea550cec659 --- /dev/null +++ b/draftlogs/6743_fix.md @@ -0,0 +1 @@ + - Fix range interactions affecting partial ranges in other subplots [[#6743](https://github.com/plotly/plotly.js/pull/6743)]