From f54387137e37ba5828e1ef6d90b18af0c4f78b31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 12 Aug 2016 13:37:14 -0400 Subject: [PATCH 1/4] assign fullTrace._input before apply-transform - so that transform can use fullTrace._input, index and _expandedIndex --- src/plots/plots.js | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/plots/plots.js b/src/plots/plots.js index a5c34a36dd9..4e78d97cd67 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -650,6 +650,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 +678,6 @@ plots.supplyDataDefaults = function(dataIn, dataOut, layout) { } } else { - fullTrace.index = i; - fullTrace._input = trace; - fullTrace._expandedIndex = cnt; - pushModule(fullTrace); } } From e92aaa6e6e0d5198d29f4ab586d52ddacec96993 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 12 Aug 2016 13:38:54 -0400 Subject: [PATCH 2/4] add globalTransforms config argument - transform options can be specified using the config arg or globally using Plotly.setPlotConfig() - global transforms are applied to all traces and are supplied before all other trace transforms. --- src/plot_api/plot_config.js | 6 ++++- src/plots/plots.js | 12 ++++++---- test/jasmine/tests/transforms_test.js | 34 +++++++++++++++++++++++++++ 3 files changed, 47 insertions(+), 5 deletions(-) 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 4e78d97cd67..f20de7ded8d 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 @@ -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 || []; - var containerIn = traceIn.transforms, + if(!Array.isArray(traceIn.transforms) && globalTransforms.length === 0) return; + + 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..dbb2c0a9c01 100644 --- a/test/jasmine/tests/transforms_test.js +++ b/test/jasmine/tests/transforms_test.js @@ -63,6 +63,40 @@ 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('supplyDataDefaults should apply the transform while', function() { var dataIn = [{ x: [-2, -2, 1, 2, 3], From 8cbbb8c22adfce1107d628845e4441c0bafaa410 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 12 Aug 2016 15:05:23 -0400 Subject: [PATCH 3/4] add fallback for gd._context - Plots.supplyDefaults({data: [], layout: {}}) should work always! --- src/plots/plots.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/plots/plots.js b/src/plots/plots.js index f20de7ded8d..f5e0e213132 100644 --- a/src/plots/plots.js +++ b/src/plots/plots.js @@ -472,7 +472,7 @@ plots.supplyDefaults = function(gd) { newFullLayout._dataLength = newData.length; // then do the data - newFullLayout._globalTransforms = gd._context.globalTransforms; + newFullLayout._globalTransforms = (gd._context || {}).globalTransforms; plots.supplyDataDefaults(newData, newFullData, newFullLayout); // attach helper method to check whether a plot type is present on graph From 6af72d0a845cdac46d5fe98f14818ea6f9f70b5b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C3=89tienne=20T=C3=A9treault-Pinard?= Date: Fri, 12 Aug 2016 15:06:01 -0400 Subject: [PATCH 4/4] test: add test checking arg passed to transform methods --- test/jasmine/tests/transforms_test.js | 39 +++++++++++++++++++++++++++ 1 file changed, 39 insertions(+) diff --git a/test/jasmine/tests/transforms_test.js b/test/jasmine/tests/transforms_test.js index dbb2c0a9c01..1344518c8d7 100644 --- a/test/jasmine/tests/transforms_test.js +++ b/test/jasmine/tests/transforms_test.js @@ -97,6 +97,45 @@ describe('one-to-one transforms:', function() { }, '- 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],