diff --git a/src/plot_api/plot_config.js b/src/plot_api/plot_config.js index 7214c28c60a..71635c0d816 100644 --- a/src/plot_api/plot_config.js +++ b/src/plot_api/plot_config.js @@ -94,7 +94,11 @@ module.exports = { // Turn all console logging on or off (errors will be thrown) // This should ONLY be set via Plotly.setPlotConfig - logging: false + logging: false, + + // Set global transform to be applied to all traces with no + // specification needed + globalTransforms: [] }; // where and how the background gets set can be overridden by context diff --git a/src/plots/plots.js b/src/plots/plots.js index a5c34a36dd9..f5e0e213132 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -472,6 +472,7 @@ plots.supplyDefaults = function(gd) { newFullLayout._dataLength = newData.length; // then do the data + newFullLayout._globalTransforms = (gd._context || {}).globalTransforms; plots.supplyDataDefaults(newData, newFullData, newFullLayout); // attach helper method to check whether a plot type is present on graph @@ -650,6 +651,10 @@ plots.supplyDataDefaults = function(dataIn, dataOut, layout) { var trace = dataIn[i], fullTrace = plots.supplyTraceDefaults(trace, cnt, layout); + fullTrace.index = i; + fullTrace._input = trace; + fullTrace._expandedIndex = cnt; + if(fullTrace.transforms && fullTrace.transforms.length) { var expandedTraces = applyTransforms(fullTrace, dataOut, layout); @@ -674,10 +679,6 @@ plots.supplyDataDefaults = function(dataIn, dataOut, layout) { } } else { - fullTrace.index = i; - fullTrace._input = trace; - fullTrace._expandedIndex = cnt; - pushModule(fullTrace); } } @@ -750,13 +751,16 @@ plots.supplyTraceDefaults = function(traceIn, traceIndex, layout) { }; function supplyTransformDefaults(traceIn, traceOut, layout) { - if(!Array.isArray(traceIn.transforms)) return; + var globalTransforms = layout._globalTransforms || []; + + if(!Array.isArray(traceIn.transforms) && globalTransforms.length === 0) return; - var containerIn = traceIn.transforms, + var containerIn = traceIn.transforms || [], + transformList = globalTransforms.concat(containerIn), containerOut = traceOut.transforms = []; - for(var i = 0; i < containerIn.length; i++) { - var transformIn = containerIn[i], + for(var i = 0; i < transformList.length; i++) { + var transformIn = transformList[i], type = transformIn.type, _module = transformsRegistry[type], transformOut; diff --git a/test/jasmine/tests/transforms_test.js b/test/jasmine/tests/transforms_test.js index d95eb1319bd..1344518c8d7 100644 --- a/test/jasmine/tests/transforms_test.js +++ b/test/jasmine/tests/transforms_test.js @@ -63,6 +63,79 @@ describe('one-to-one transforms:', function() { expect(traceOut.y).toBe(traceIn.y); }); + it('supplyTraceDefaults should honored global transforms', function() { + var traceIn = { + y: [2, 1, 2], + transforms: [{ + type: 'filter', + operation: '>', + value: '0', + filtersrc: 'x' + }] + }; + + var layout = { + _globalTransforms: [{ + type: 'filter' + }] + }; + + var traceOut = Plots.supplyTraceDefaults(traceIn, 0, layout); + + expect(traceOut.transforms[0]).toEqual({ + type: 'filter', + operation: '=', + value: 0, + filtersrc: 'x' + }, '- global first'); + + expect(traceOut.transforms[1]).toEqual({ + type: 'filter', + operation: '>', + value: 0, + filtersrc: 'x' + }, '- trace second'); + }); + + it('should pass correctly arguments to transform methods', function() { + var transformIn = { type: 'fake' }; + var transformOut = {}; + + var dataIn = [{ + transforms: [transformIn] + }]; + + var layout = {}; + + function assertSupplyDefaultsArgs(_transformIn, traceOut, _layout) { + expect(_transformIn).toBe(transformIn); + expect(_layout).toBe(layout); + + return transformOut; + } + + function assertTransformArgs(dataOut, opts) { + expect(dataOut[0]._input).toBe(dataIn[0]); + expect(opts.transform).toBe(transformOut); + expect(opts.fullTrace._input).toBe(dataIn[0]); + expect(opts.layout).toBe(layout); + + return dataOut; + } + + var fakeTransformModule = { + moduleType: 'transform', + name: 'fake', + attributes: {}, + supplyDefaults: assertSupplyDefaultsArgs, + transform: assertTransformArgs + }; + + Plotly.register(fakeTransformModule); + Plots.supplyDataDefaults(dataIn, [], layout); + delete Plots.transformsRegistry.fake; + }); + it('supplyDataDefaults should apply the transform while', function() { var dataIn = [{ x: [-2, -2, 1, 2, 3],