8000 restyle/relayout refactor by alexcjohnson · Pull Request #1999 · plotly/plotly.js · GitHub
[go: up one dir, main page]

Skip to content
8000

restyle/relayout refactor #1999

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 43 commits into from
Sep 20, 2017
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
43 commits
Select commit Hold shift + click to select a range
284c87f
remove obsolete comment in gl3d
alexcjohnson Sep 14, 2017
b9826c8
change overrideAll API to nested/from-root only
alexcjohnson Sep 14, 2017
7c38a4a
clean up restyle/relayout flag names
alexcjohnson Sep 14, 2017
96cc57f
clean up editTypes/impliedEdits and formalize & document their schema…
alexcjohnson Sep 14, 2017
cb94e95
test restrictions on component xaxis/yaxis schemas
alexcjohnson Sep 15, 2017
238e248
preserve impliedEdits: {key: undefined} by extendDeepAll
alexcjohnson Sep 15, 2017
42662ba
comments on relative_attr regexps
alexcjohnson Sep 15, 2017
50aa1ca
include schema in dist
alexcjohnson Sep 15, 2017
62a1392
fix plotschema test for metaKeys
alexcjohnson Sep 15, 2017
87b26d5
test order-independence of trace/transform/component registration
alexcjohnson Sep 18, 2017
040ed1b
test colorbar editing
alexcjohnson Sep 19, 2017
388a7fe
abstract - and fix - automatic axis type clearing
alexcjohnson Sep 19, 2017
6e8a68c
coerceTraceIndices earlier so clearAxisTypes can use it
alexcjohnson Sep 19, 2017
4f8fc66
move clearAxisTypes into helpers
alexcjohnson Sep 19, 2017
97ddf48
update jsdom to v11.2 with new API
alexcjohnson Sep 19, 2017
fe7db79
oops didn't mean to commit that commented out...
alexcjohnson Sep 19, 2017
68f5dbc
fix and test errorbar visibility toggling
alexcjohnson Sep 19, 2017
d15e541
layout.showlegend test
alexcjohnson Sep 19, 2017
7ec1634
closes #615 - something else in this PR fixed it, just nailing a test
alexcjohnson Sep 19, 2017
a107466
fix #358 - restyling orientation
alexcjohnson Sep 20, 2017
42805c2
test histogram changing data type
alexcjohnson Sep 20, 2017
8d9feaf
fix #2020 - editing plots with multiple histograms
alexcjohnson Sep 20, 2017
0a98a6d
lint
alexcjohnson Sep 20, 2017
e4227aa
move checkTicks into custom_assertions
alexcjohnson Sep 20, 2017
0729921
load custom_matchers globally, and refactor negateIf as a method
alexcjohnson Sep 20, 2017
407ae5a
pull custom_matchers out of requirejs bundle test
alexcjohnson Sep 20, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
test - and fix - most of the relayout doextras
  • Loading branch information
alexcjohnson committed Sep 13, 2017
commit 4d3e2ec72babc25eea3a051d946f3d0904c41a17
11 changes: 9 additions & 2 deletions src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -1949,7 +1949,10 @@ function _relayout(gd, aobj) {
if(attr in aobj || helpers.hasParent(aobj, attr)) return;

var p = Lib.nestedProperty(layout, attr);
if(!(attr in undoit)) undoit[attr] = p.get();
if(!(attr in undoit)) {
var undoVal = p.get();
undoit[attr] = undoVal === undefined ? null : undoVal;
}
if(val !== undefined) p.set(val);
}

Expand Down Expand Up @@ -2012,7 +2015,7 @@ function _relayout(gd, aobj) {

// axis reverse is special - it is its own inverse
// op and has no flag.
undoit[ai] = (pleaf === 'reverse') ? vi : vOld;
undoit[ai] = (pleaf === 'reverse') ? vi : (vOld === undefined ? null : vOld);

// Setting width or height to null must reset the graph's width / height
// back to its initial value as computed during the first pass in Plots.plotAutoSize.
Expand Down Expand Up @@ -2083,6 +2086,9 @@ function _relayout(gd, aobj) {

if(toLog || fromLog) {
if(!ax || !ax.range) {
// 2D never gets here, but 3D does
// I don't think this is needed, but left here in case there
// are edge cases I'm not thinking of.
doextra(ptrunk + '.autorange', true);
}
else if(!parentFull.autorange) {
Expand Down Expand Up @@ -2122,6 +2128,7 @@ function _relayout(gd, aobj) {
// any other type changes: the range from the previous type
// will not make sense, so autorange it.
doextra(ptrunk + '.autorange', true);
doextra(ptrunk + '.range', null);
}
Lib.nestedProperty(fullLayout, ptrunk + '._inputRange').set(null);
}
Expand Down
6 changes: 6 additions & 0 deletions src/plots/gl3d/layout/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,12 @@ function handleGl3dDefaults(sceneLayoutIn, sceneLayoutOut, coerce, opts) {
sceneLayoutIn.aspectratio = sceneLayoutOut.aspectratio = {x: 1, y: 1, z: 1};

if(aspectMode === 'manual') sceneLayoutOut.aspectmode = 'auto';

/*
* kind of like autorange - we need the calculated aspectmode back in
* the input layout or relayout can cause problems later
*/
sceneLayoutIn.aspectmode = sceneLayoutOut.aspectmode;
}

supplyGl3dAxisLayoutDefaults(sceneLayoutIn, sceneLayoutOut, {
Expand Down
40 changes: 39 additions & 1 deletion test/jasmine/tests/gl3dlayout_test.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
var Plotly = require('@lib/index');
var Gl3d = require('@src/plots/gl3d');

var tinycolor = require('tinycolor2');
var Color = require('@src/components/color');

var createGraphDiv = require('../assets/create_graph_div');
var destroyGraphDiv = require('../assets/destroy_graph_div');
var fail = require('../assets/fail_test');


describe('Test Gl3d layout defaults', function() {
'use strict';
Expand Down Expand Up @@ -227,7 +232,8 @@ describe('Test Gl3d layout defaults', function() {

supplyLayoutDefaults(layoutIn, layoutOut, fullData);
expect(layoutIn.scene).toEqual({
aspectratio: { x: 1, y: 1, z: 1 }
aspectratio: { x: 1, y: 1, z: 1 },
aspectmode: 'auto'
});
});

Expand Down Expand Up @@ -262,3 +268,35 @@ describe('Test Gl3d layout defaults', function() {
});
});
});

describe('Gl3d layout edge cases', function() {
var gd;

beforeEach(function() {gd = createGraphDiv(); });
afterEach(destroyGraphDiv);

it('should handle auto aspect ratio correctly on data changes', function(done) {
Plotly.plot(gd, [{x: [1, 2], y: [1, 3], z: [1, 4], type: 'scatter3d'}])
.then(function() {
var aspect = gd.layout.scene.aspectratio;
expect(aspect.x).toBeCloseTo(0.5503);
expect(aspect.y).toBeCloseTo(1.1006);
expect(aspect.z).toBeCloseTo(1.6510);

return Plotly.restyle(gd, 'x', [[1, 6]]);
})
.then(function() {
/*
* Check that now it's the same as if you had just made the plot with
* x: [1, 6] in the first place
*/
var aspect = gd.layout.scene.aspectratio;
expect(aspect.x).toBeCloseTo(1.6091);
expect(aspect.y).toBeCloseTo(0.6437);
expect(aspect.z).toBeCloseTo(0.9655);
})
.catch(fail)
.then(done);
});

});
168 changes: 167 additions & 1 deletion test/jasmine/tests/plot_api_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ var Plotly = require('@lib/index');
var PlotlyInternal = require('@src/plotly');
var Plots = require('@src/plots/plots');
var Lib = require('@src/lib');
var Queue = require('@src/lib/queue');
var Scatter = require('@src/traces/scatter');
var Bar = require('@src/traces/bar');
var Legend = require('@src/components/legend');
Expand Down Expand Up @@ -113,9 +114,18 @@ describe('Test plot api', function() {

beforeEach(function() {
gd = createGraphDiv();

// some of these tests use the undo/redo queue
// OK, this is weird... the undo/redo queue length is a global config only.
// It's ignored on the plot, even though the queue itself is per-plot.
// We may ditch this later, but probably not until v2
Plotly.setPlotConfig({queueLength: 3});
});

afterEach(destroyGraphDiv);
afterEach(function() {
destroyGraphDiv();
Plotly.setPlotConfig({queueLength: 0});
});

it('should update the plot clipPath if the plot is resized', function(done) {

Expand Down Expand Up @@ -331,6 +341,162 @@ describe('Test plot api', function() {
.catch(fail)
.then(done);
});

it('clears autorange when you modify a range or part of a range', function(done) {
var initialXRange;
var initialYRange;

Plotly.plot(gd, [{x: [1, 2], y: [1, 2]}])
.then(function() {
expect(gd.layout.xaxis.autorange).toBe(true);
expect(gd.layout.yaxis.autorange).toBe(true);

initialXRange = gd.layout.xaxis.range.slice();
initialYRange = gd.layout.yaxis.range.slice();

return Plotly.relayout(gd, {'xaxis.range': [0, 1], 'yaxis.range[1]': 3});
})
.then(function() {
expect(gd.layout.xaxis.autorange).toBe(false);
expect(gd.layout.xaxis.range).toEqual([0, 1]);
expect(gd.layout.yaxis.autorange).toBe(false);
expect(gd.layout.yaxis.range[1]).toBe(3);

return Plotly.relayout(gd, {'xaxis.autorange': true, 'yaxis.autorange': true});
})
.then(function() {
expect(gd.layout.xaxis.range).toEqual(initialXRange);
expect(gd.layout.yaxis.range).toEqual(initialYRange);

// finally, test that undoing autorange puts back the previous explicit range
return Queue.undo(gd);
})
.then(function() {
expect(gd.layout.xaxis.autorange).toBe(false);
expect(gd.layout.xaxis.range).toEqual([0, 1]);
expect(gd.layout.yaxis.autorange).toBe(false);
expect(gd.layout.yaxis.range[1]).toBe(3);
})
.catch(fail)
.then(done);
});

it('sets aspectmode to manual when you provide any aspectratio', function(done) {
Plotly.plot(gd, [{x: [1, 2], y: [1, 2], z: [1, 2], type: 'scatter3d'}])
.then(function() {
expect(gd.layout.scene.aspectmode).toBe('auto');

return Plotly.relayout(gd, {'scene.aspectratio.x': 2});
})
.then(function() {
expect(gd.layout.scene.aspectmode).toBe('manual');

return Queue.undo(gd);
})
.then(function() {
expect(gd.layout.scene.aspectmode).toBe('auto');
})
.catch(fail)
.then(done);
});

it('sets tickmode to linear when you edit tick0 or dtick', function(done) {
Plotly.plot(gd, [{x: [1, 2], y: [1, 2]}])
.then(function() {
expect(gd.layout.xaxis.tickmode).toBeUndefined();
expect(gd.layout.yaxis.tickmode).toBeUndefined();

return Plotly.relayout(gd, {'xaxis.tick0': 0.23, 'yaxis.dtick': 0.34});
})
.then(function() {
expect(gd.layout.xaxis.tickmode).toBe('linear');
expect(gd.layout.yaxis.tickmode).toBe('linear');

return Queue.undo(gd);
})
.then(function() {
expect(gd.layout.xaxis.tickmode).toBeUndefined();
expect(gd.layout.yaxis.tickmode).toBeUndefined();

expect(gd.layout.xaxis.tick0).toBeUndefined();
expect(gd.layout.yaxis.dtick).toBeUndefined();
})
.catch(fail)
.then(done);
});

it('updates non-auto ranges for linear/log changes', function(done) {
Plotly.plot(gd, [{x: [3, 5], y: [3, 5]}], {
xaxis: {range: [1, 10]},
yaxis: {type: 'log', range: [0, 1]}
})
.then(function() {
return Plotly.relayout(gd, {'xaxis.type': 'log', 'yaxis.type': 'linear'});
})
.then(function() {
expect(gd.layout.xaxis.range).toBeCloseToArray([0, 1], 5);
expect(gd.layout.yaxis.range).toBeCloseToArray([1, 10], 5);

return Queue.undo(gd);
})
.then(function() {
expect(gd.layout.xaxis.range).toBeCloseToArray([1, 10], 5);
expect(gd.layout.yaxis.range).toBeCloseToArray([0, 1], 5);
})
.catch(fail)
.then(done);
});

it('respects reversed autorange when switching linear to log', function(done) {
Plotly.plot(gd, [{x: [1, 2], y: [1, 2]}])
.then(function() {
// Ideally we should change this to xaxis.autorange: 'reversed'
// but that's a weird disappearing setting used just to force
// an initial reversed autorange. Proposed v2 change at:
// https://github.com/plotly/plotly.js/issues/420#issuecomment-323435082
return Plotly.relayout(gd, 'xaxis.reverse', true);
})
.then(function() {
var xRange = gd.layout.xaxis.range;
expect(xRange[1]).toBeLessThan(xRange[0]);
expect(xRange[0]).toBeGreaterThan(1);

return Plotly.relayout(gd, 'xaxis.type', 'log');
})
.then(function() {
var xRange = gd.layout.xaxis.range;
expect(xRange[1]).toBeLessThan(xRange[0]);
// make sure it's a real loggy range
expect(xRange[0]).toBeLessThan(1);
})
.catch(fail)
.then(done);
});

it('autoranges automatically when switching to/from any other axis type than linear <-> log', function(done) {
Plotly.plot(gd, [{x: ['1.5', '0.8'], y: [1, 2]}], {xaxis: {range: [0.6, 1.7]}})
.then(function() {
expect(gd.layout.xaxis.autorange).toBeUndefined();
expect(gd._fullLayout.xaxis.type).toBe('linear');
expect(gd.layout.xaxis.range).toEqual([0.6, 1.7]);

return Plotly.relayout(gd, 'xaxis.type', 'category');
})
.then(function() {
expect(gd.layout.xaxis.autorange).toBe(true);
expect(gd._fullLayout.xaxis.type).toBe('category');
expect(gd.layout.xaxis.range[0]).toBeLessThan(0);

return Queue.undo(gd);
})
.then(function() {
expect(gd.layout.xaxis.autorange).toBeUndefined();
expect(gd._fullLayout.xaxis.type).toBe('linear');
expect(gd.layout.xaxis.range).toEqual([0.6, 1.7]);
})
.catch(fail)
.then(done);
});
});

describe('Plotly.relayout subroutines switchboard', function() {
Expand Down
0