Skip to content
6 changes: 3 additions & 3 deletions src/components/grid/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ var gridAttrs = {
valType: 'info_array',
freeLength: true,
dimensions: 2,
items: {valType: 'enumerated', values: [counterRegex('xy').toString(), '']},
items: {valType: 'enumerated', values: [counterRegex('xy').toString(), ''], editType: 'plot'},
role: 'info',
editType: 'plot',
description: [
Expand All @@ -69,7 +69,7 @@ var gridAttrs = {
xaxes: {
valType: 'info_array',
freeLength: true,
items: {valType: 'enumerated', values: [cartesianIdRegex.x.toString(), '']},
items: {valType: 'enumerated', values: [cartesianIdRegex.x.toString(), ''], editType: 'plot'},
role: 'info',
editType: 'plot',
description: [
Expand All @@ -83,7 +83,7 @@ var gridAttrs = {
yaxes: {
valType: 'info_array',
freeLength: true,
items: {valType: 'enumerated', values: [cartesianIdRegex.y.toString(), '']},
items: {valType: 'enumerated', values: [cartesianIdRegex.y.toString(), ''], editType: 'plot'},
role: 'info',
editType: 'plot',
description: [
Expand Down
29 changes: 15 additions & 14 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1857,20 +1857,21 @@ function _relayout(gd, aobj) {
throw new Error('cannot set ' + ai + 'and a parent attribute simultaneously');
}

var p = Lib.nestedProperty(layout, ai),
vi = aobj[ai],
plen = p.parts.length,
// p.parts may end with an index integer if the property is an array
pend = typeof p.parts[plen - 1] === 'string' ? (plen - 1) : (plen - 2),
// last property in chain (leaf node)
pleaf = p.parts[pend],
// leaf plus immediate parent
pleafPlus = p.parts[pend - 1] + '.' + pleaf,
// trunk nodes (everything except the leaf)
ptrunk = p.parts.slice(0, pend).join('.'),
parentIn = Lib.nestedProperty(gd.layout, ptrunk).get(),
parentFull = Lib.nestedProperty(fullLayout, ptrunk).get(),
vOld = p.get();
var p = Lib.nestedProperty(layout, ai);
var vi = aobj[ai];
var plen = p.parts.length;
// p.parts may end with an index integer if the property is an array
var pend = plen - 1;
while(pend > 0 && typeof p.parts[plen - 1] !== 'string') { pend--; }
// last property in chain (leaf node)
var pleaf = p.parts[pend];
// leaf plus immediate parent
var pleafPlus = p.parts[pend - 1] + '.' + pleaf;
// trunk nodes (everything except the leaf)
var ptrunk = p.parts.slice(0, pend).join('.');
var parentIn = Lib.nestedProperty(gd.layout, ptrunk).get();
var parentFull = Lib.nestedProperty(fullLayout, ptrunk).get();
var vOld = p.get();

if(vi === undefined) continue;

Expand Down
4 changes: 2 additions & 2 deletions src/plots/domain.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ exports.attributes = function(opts, extra) {
role: 'info',
editType: opts.editType,
items: [
{valType: 'number', min: 0, max: 1},
{valType: 'number', min: 0, max: 1}
{valType: 'number', min: 0, max: 1, editType: opts.editType},
{valType: 'number', min: 0, max: 1, editType: opts.editType}
],
dflt: [0, 1]
};
Expand Down
86 changes: 67 additions & 19 deletions test/jasmine/tests/plot_api_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,8 @@ describe('Test plot api', function() {
'doCamera'
];

var gd;

beforeAll(function() {
mockedMethods.forEach(function(m) {
spyOn(subroutines, m);
Expand All @@ -523,8 +525,20 @@ describe('Test plot api', function() {
return gd;
}

function expectModeBarOnly(msg) {
expect(gd.calcdata).toBeDefined(msg);
expect(subroutines.doModeBar.calls.count()).toBeGreaterThan(0, msg);
expect(subroutines.layoutReplot.calls.count()).toBe(0, msg);
}

function expectReplot(msg) {
expect(gd.calcdata).toBeDefined(msg);
expect(subroutines.doModeBar.calls.count()).toBe(0, msg);
expect(subroutines.layoutReplot.calls.count()).toBeGreaterThan(0, msg);
}

it('should trigger replot (but not recalc) when switching into select or lasso dragmode for scattergl traces', function() {
var gd = mock({
gd = mock({
data: [{
type: 'scattergl',
x: [1, 2, 3],
Expand All @@ -535,35 +549,69 @@ describe('Test plot api', function() {
}
});

function expectModeBarOnly() {
expect(gd.calcdata).toBeDefined();
expect(subroutines.doModeBar).toHaveBeenCalled();
expect(subroutines.layoutReplot).not.toHaveBeenCalled();
}

function expectReplot() {
expect(gd.calcdata).toBeDefined();
expect(subroutines.doModeBar).not.toHaveBeenCalled();
expect(subroutines.layoutReplot).toHaveBeenCalled();
}

Plotly.relayout(gd, 'dragmode', 'pan');
expectModeBarOnly();
expectModeBarOnly('pan');

Plotly.relayout(mock(gd), 'dragmode', 'lasso');
expectReplot();
expectReplot('lasso 1');

Plotly.relayout(mock(gd), 'dragmode', 'select');
expectModeBarOnly();
expectModeBarOnly('select 1');

Plotly.relayout(mock(gd), 'dragmode', 'lasso');
expectModeBarOnly();
expectModeBarOnly('lasso 2');

Plotly.relayout(mock(gd), 'dragmode', 'zoom');
expectModeBarOnly();
expectModeBarOnly('zoom');

Plotly.relayout(mock(gd), 'dragmode', 'select');
expectReplot();
expectReplot('select 2');
});

it('should trigger replot (but not recalc) when changing attributes that affect axis length/range', function() {
// but axis.autorange itself is NOT here, because setting it from false to true requires an
// autorange so that we calculate _min and _max, which we ignore if autorange is off.
var axLayoutEdits = {
'xaxis.rangemode': 'tozero',
'xaxis.domain': [0.2, 0.8],
'xaxis.domain[1]': 0.7,
'yaxis.domain': [0.1, 0.9],
'yaxis.domain[0]': 0.3,
'yaxis.overlaying': 'y2',
'margin.l': 50,
'margin.r': 20,
'margin.t': 1,
'margin.b': 5,
'margin.autoexpand': false,
height: 567,
width: 432,
'grid.rows': 2,
'grid.columns': 3,
'grid.xgap': 0.5,
'grid.ygap': 0,
'grid.roworder': 'bottom to top',
'grid.pattern': 'independent',
'grid.yaxes': ['y2', 'y'],
'grid.xaxes[0]': 'x2',
'grid.domain': {x: [0, 0.4], y: [0.6, 1]},
'grid.domain.x': [0.01, 0.99],
'grid.domain.y[0]': 0.33,
'grid.subplots': [['', 'xy'], ['x2y2', '']],
'grid.subplots[1][1]': 'xy'
};

for(var attr in axLayoutEdits) {
gd = mock({
data: [{y: [1, 2]}, {y: [4, 3], xaxis: 'x2', yaxis: 'y2'}],
layout: {
xaxis2: {domain: [0.6, 0.9]},
yaxis2: {domain: [0.6, 0.9]}
}
});

Plotly.relayout(gd, attr, axLayoutEdits[attr]);
expectReplot(attr);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💯 / 💯 test!

}
});
});

Expand Down