Skip to content

Transform react #2577

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 26 commits into from
Apr 26, 2018
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
26 commits
Select commit Hold shift + click to select a range
bbe3533
remove no longer needed hack for finance in findArrayAttributes
alexcjohnson Apr 18, 2018
ed24765
_commonLength -> _length
alexcjohnson Apr 18, 2018
fcc459d
fix #2508, fix #2470 - problems with Plotly.react and aggregate trans…
alexcjohnson Apr 18, 2018
7044a13
standardize transforms handling of _length
alexcjohnson Apr 19, 2018
88b7b43
:racehorse: refactor sort transform from O(n^2) to O(n)
alexcjohnson Apr 19, 2018
cf4c9c3
heatmap&carpet/has_columns -> Lib.is1D
alexcjohnson Apr 20, 2018
e84d4b9
close #1410 - yes, stop pruning in nestedProperty
alexcjohnson Apr 20, 2018
b436d52
ensure every trace defines _length in supplyDefaults, and abort trans…
alexcjohnson Apr 22, 2018
2a41f9e
react+transforms PR review edits
alexcjohnson Apr 24, 2018
965bcfb
fixes and test for checklist in #2508
alexcjohnson Apr 24, 2018
6fae229
some fixes and tests for empty data arrays
alexcjohnson Apr 24, 2018
79295f1
rename violins mock that doesn't contain violin traces
alexcjohnson Apr 25, 2018
5e9aa65
transforms mock
alexcjohnson Apr 26, 2018
690eb95
clean up keyedContainer for possibly missing array
alexcjohnson Apr 26, 2018
a244cec
violin should not explicitly set whiskerwidth
alexcjohnson Apr 26, 2018
92bd5d2
add _length and stop slicing in scattercarpet
alexcjohnson Apr 26, 2018
dc6de2f
clean up handling of colorscale defaults
alexcjohnson Apr 26, 2018
03956e1
include count aggregates in _arrayAttrs - so they remap correctly
alexcjohnson Apr 26, 2018
f439e41
in diffData I had _fullInput in the new trace, but not the old!
alexcjohnson Apr 26, 2018
e47e6a9
_compareAsJSON for groupby styles
alexcjohnson Apr 26, 2018
aa30ad6
update plot_api_test to :lock: recent changes in react/transforms etc
alexcjohnson Apr 26, 2018
4c70826
lint
alexcjohnson Apr 26, 2018
7279b55
+shapes & annotations3d in react-noop test
alexcjohnson Apr 26, 2018
3e250df
tweak docs & remove commented-out code
alexcjohnson Apr 26, 2018
cd08479
reactWith -> reactTo
alexcjohnson Apr 26, 2018
0414147
separate svg and gl traces in react-noop tests
alexcjohnson Apr 26, 2018
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
8 changes: 7 additions & 1 deletion src/plot_api/plot_api.js
Original file line number Diff line number Diff line change
Expand Up @@ -2267,7 +2267,10 @@ exports.react = function(gd, data, layout, config) {
gd.layout = layout || {};
helpers.cleanLayout(gd.layout);

Plots.supplyDefaults(gd);
// "true" skips updating calcdata and remapping arrays from calcTransforms,
// which supplyDefaults usually does at the end, but we may need to NOT do
// if the diff (which we haven't determined yet) says we'll recalc
Plots.supplyDefaults(gd, true);
Copy link
Contributor

@etpinard etpinard Apr 23, 2018

Choose a reason for hiding this comment

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

I'm not a big fan of this pattern.

At the very least we should turn this into Plots.supplyDefaults(gd, {skipDefaultsUpdateCalc: 1}) to make it more readable and extendable.

Personally, I'd vote for removing the newly added Plots.supplyDefaultsUpdateCalc() from Plots.supplyDefaults and call Plotly.supplyDefaultsUpdateCalc after Plots.supplyDefaults in the places that new it.

On master, we have:

image

where the calls in validate.js and rangeslider/draw.js (and maybe more) don't need to update calc.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Perhaps the name supplyDefaultsUpdateCalc isn't the best - though you could argue the same about calcTransform, which happens during the calc step but updates the data arrays in _fullData. supplyDefaultsUpdateCalc has one simple function when there are no transforms, to attach the new traces to the old calcdata in case we're not going to run a recalc, but when there are transforms it also (first) pulls the transformed array attributes back from the old fullTrace to the new one. So I think in fact we do need this in most instances, and there are some external callers (like streambed) that depend on this as well.

So I'm going to keep it as part of the default supplyDefaults behavior, but I'm happy to make it into an options object for clarity.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

cleaner supplyDefaults API -> 2a41f9e


var newFullData = gd._fullData;
var newFullLayout = gd._fullLayout;
Expand All @@ -2289,6 +2292,9 @@ exports.react = function(gd, data, layout, config) {

// clear calcdata if required
if(restyleFlags.calc || relayoutFlags.calc) gd.calcdata = undefined;
// otherwise do the calcdata updates and calcTransform array remaps that we skipped earlier
else Plots.supplyDefaultsUpdateCalc(gd.calcdata, newFullData);

if(relayoutFlags.margins) helpers.clearAxisAutomargins(gd);

// Note: what restyle/relayout use impliedEdits and clearAxisTypes for
Expand Down
56 changes: 33 additions & 23 deletions src/plot_api/plot_schema.js
Original file line number Diff line number Diff line change
Expand Up @@ -171,9 +171,12 @@ exports.isValObject = function(obj) {
exports.findArrayAttributes = function(trace) {
var arrayAttributes = [];
var stack = [];
var isArrayStack = [];
var baseContainer, baseAttrName;

function callback(attr, attrName, attrs, level) {
stack = stack.slice(0, level).concat([attrName]);
isArrayStack = isArrayStack.slice(0, level).concat([attr && attr._isLinkedToArray]);

var splittableAttr = (
attr &&
Expand All @@ -190,48 +193,55 @@ exports.findArrayAttributes = function(trace) {

if(!splittableAttr) return;

var astr = toAttrString(stack);
var val = Lib.nestedProperty(trace, astr).get();
if(!Lib.isArrayOrTypedArray(val)) return;

arrayAttributes.push(astr);
crawlIntoTrace(baseContainer, 0, '');
}

function toAttrString(stack) {
return stack.join('.');
function crawlIntoTrace(container, i, astrPartial) {
var item = container[stack[i]];
var newAstrPartial = astrPartial + stack[i];
if(i === stack.length - 1) {
if(Lib.isArrayOrTypedArray(item)) {
arrayAttributes.push(baseAttrName + newAstrPartial);
}
}
else {
if(isArrayStack[i]) {
if(Array.isArray(item)) {
for(var j = 0; j < item.length; j++) {
if(Lib.isPlainObject(item[j])) {
crawlIntoTrace(item[j], i + 1, newAstrPartial + '[' + j + '].');
}
}
}
}
else if(Lib.isPlainObject(item)) {
crawlIntoTrace(item, i + 1, newAstrPartial + '.');
}
}
}

baseContainer = trace;
baseAttrName = '';
exports.crawl(baseAttributes, callback);
if(trace._module && trace._module.attributes) {
exports.crawl(trace._module.attributes, callback);
}

if(trace.transforms) {
var transforms = trace.transforms;

var transforms = trace.transforms;
if(transforms) {
for(var i = 0; i < transforms.length; i++) {
var transform = transforms[i];
var module = transform._module;

if(module) {
stack = ['transforms[' + i + ']'];
baseAttrName = 'transforms[' + i + '].';
baseContainer = transform;

exports.crawl(module.attributes, callback, 1);
exports.crawl(module.attributes, callback);
}
}
}

// Look into the fullInput module attributes for array attributes
// to make sure that 'custom' array attributes are detected.
//
// At the moment, we need this block to make sure that
// ohlc and candlestick 'open', 'high', 'low', 'close' can be
// used with filter and groupby transforms.
if(trace._fullInput && trace._fullInput._module && trace._fullInput._module.attributes) {
exports.crawl(trace._fullInput._module.attributes, callback);
arrayAttributes = Lib.filterUnique(arrayAttributes);
}

return arrayAttributes;
};

Expand Down
2 changes: 1 addition & 1 deletion src/plots/cartesian/type_defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,7 +107,7 @@ function getFirstNonEmptyTrace(data, id, axLetter) {
var trace = data[i];

if(trace.type === 'splom' &&
trace._commonLength > 0 &&
trace._length > 0 &&
trace['_' + axLetter + 'axes'][id]
) {
return trace;
Expand Down
30 changes: 17 additions & 13 deletions src/plots/plots.js
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ var extraFormatKeys = [
// gd._fullLayout._transformModules
// is a list of all the transform modules invoked.
//
plots.supplyDefaults = function(gd) {
plots.supplyDefaults = function(gd, skipCalcUpdate) {
var oldFullLayout = gd._fullLayout || {};

if(oldFullLayout._skipDefaults) {
Expand Down Expand Up @@ -458,24 +458,28 @@ plots.supplyDefaults = function(gd) {
}

// update object references in calcdata
if(oldCalcdata.length === newFullData.length) {
for(i = 0; i < newFullData.length; i++) {
var newTrace = newFullData[i];
var cd0 = oldCalcdata[i][0];
if(cd0 && cd0.trace) {
if(cd0.trace._hasCalcTransform) {
remapTransformedArrays(cd0, newTrace);
} else {
cd0.trace = newTrace;
}
}
}
if(!skipCalcUpdate && oldCalcdata.length === newFullData.length) {
plots.supplyDefaultsUpdateCalc(oldCalcdata, newFullData);
}

// sort base plot modules for consistent ordering
newFullLayout._basePlotModules.sort(sortBasePlotModules);
};

plots.supplyDefaultsUpdateCalc = function(oldCalcdata, newFullData) {
for(var i = 0; i < newFullData.length; i++) {
var newTrace = newFullData[i];
var cd0 = oldCalcdata[i][0];
if(cd0 && cd0.trace) {
if(cd0.trace._hasCalcTransform) {
remapTransformedArrays(cd0, newTrace);
Copy link
Contributor

Choose a reason for hiding this comment

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

remapTransformedArrays is only called from here, maybe we could merge it in here?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

merged and 🐎 remapTransformedArrays -> 2a41f9e

} else {
cd0.trace = newTrace;
}
}
}
};

/**
* Make a container for collecting subplots we need to display.
*
Expand Down
2 changes: 1 addition & 1 deletion src/traces/parcoords/calc.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ var wrap = require('../../lib/gup').wrap;

module.exports = function calc(gd, trace) {
var cs = !!trace.line.colorscale && Lib.isArrayOrTypedArray(trace.line.color);
var color = cs ? trace.line.color : constHalf(trace._commonLength);
var color = cs ? trace.line.color : constHalf(trace._length);
var cscale = cs ? trace.line.colorscale : [[0, trace.line.color], [1, trace.line.color]];

if(hasColorscale(trace, 'line')) {
Expand Down
6 changes: 3 additions & 3 deletions src/traces/parcoords/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ function handleLineDefaults(traceIn, traceOut, defaultColor, layout, coerce) {
// TODO: I think it would be better to keep showing lines beyond the last line color
// but I'm not sure what color to give these lines - probably black or white
// depending on the background color?
traceOut._commonLength = Math.min(traceOut._commonLength, lineColor.length);
traceOut._length = Math.min(traceOut._length, lineColor.length);
}
else {
traceOut.line.color = defaultColor;
Expand Down Expand Up @@ -84,7 +84,7 @@ function dimensionsDefaults(traceIn, traceOut) {
dimensionsOut.push(dimensionOut);
}

traceOut._commonLength = commonLength;
traceOut._length = commonLength;

return dimensionsOut;
}
Expand All @@ -108,7 +108,7 @@ module.exports = function supplyDefaults(traceIn, traceOut, defaultColor, layout
// but we can't do this in dimensionsDefaults (yet?) because line.color can also
// truncate
for(var i = 0; i < dimensions.length; i++) {
if(dimensions[i].visible) dimensions[i]._length = traceOut._commonLength;
if(dimensions[i].visible) dimensions[i]._length = traceOut._length;
}

// make default font size 10px (default is 12),
Expand Down
2 changes: 1 addition & 1 deletion src/traces/parcoords/parcoords.js
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ function model(layout, d, i) {
color: lineColor.map(d3.scale.linear().domain(dimensionExtent({
values: lineColor,
range: [line.cmin, line.cmax],
_length: trace._commonLength
_length: trace._length
}))),
blockLineCount: c.blockLineCount,
canvasOverdrag: c.overdrag * c.canvasPixelRatio
Expand Down
2 changes: 1 addition & 1 deletion src/traces/scattergl/convert.js
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ function convertStyle(gd, trace) {
}

function convertMarkerStyle(trace) {
var count = trace._length || trace._commonLength;
var count = trace._length;
var optsIn = trace.marker;
var optsOut = {};
var i;
Expand Down
2 changes: 1 addition & 1 deletion src/traces/splom/defaults.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ function handleDimensionsDefaults(traceIn, traceOut) {
if(dimOut.visible) dimOut._length = commonLength;
}

traceOut._commonLength = commonLength;
traceOut._length = commonLength;

return dimensionsOut.length;
}
Expand Down
4 changes: 2 additions & 2 deletions src/traces/splom/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ var TOO_MANY_POINTS = require('../scattergl/constants').TOO_MANY_POINTS;

function calc(gd, trace) {
var dimensions = trace.dimensions;
var commonLength = trace._commonLength;
var commonLength = trace._length;
var stash = {};
var opts = {};
// 'c' for calculated, 'l' for linear,
Expand Down Expand Up @@ -228,7 +228,7 @@ function plotOne(gd, cd0) {
scene.unselectBatch = null;

if(selectMode) {
var commonLength = trace._commonLength;
var commonLength = trace._length;

if(!scene.selectBatch) {
scene.selectBatch = [];
Expand Down
2 changes: 2 additions & 0 deletions src/transforms/aggregate.js
Original file line number Diff line number Diff line change
Expand Up @@ -254,6 +254,8 @@ exports.calcTransform = function(gd, trace, opts) {
enabled: true
});
}

trace._length = groupings.length;
};

function aggregateOneArray(gd, trace, groupings, aggregation) {
Expand Down
2 changes: 1 addition & 1 deletion test/jasmine/tests/parcoords_test.js
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ describe('parcoords initialization tests', function() {
{values: [], visible: true},
{values: [1, 2], visible: false} // shouldn't be truncated to as visible: false
]});
expect(fullTrace._commonLength).toBe(3);
expect(fullTrace._length).toBe(3);
});

it('cleans up constraintrange', function() {
Expand Down
Loading