From 9e415566e56d36b67d2d50c45fb199c362f4f083 Mon Sep 17 00:00:00 2001 From: timelyportfolio Date: Wed, 3 Aug 2016 15:57:06 -0500 Subject: [PATCH 1/9] move `transforms` to a "proper" place --- {test/jasmine/assets => src}/transforms/filter.js | 0 {test/jasmine/assets => src}/transforms/groupby.js | 0 2 files changed, 0 insertions(+), 0 deletions(-) rename {test/jasmine/assets => src}/transforms/filter.js (100%) rename {test/jasmine/assets => src}/transforms/groupby.js (100%) diff --git a/test/jasmine/assets/transforms/filter.js b/src/transforms/filter.js similarity index 100% rename from test/jasmine/assets/transforms/filter.js rename to src/transforms/filter.js diff --git a/test/jasmine/assets/transforms/groupby.js b/src/transforms/groupby.js similarity index 100% rename from test/jasmine/assets/transforms/groupby.js rename to src/transforms/groupby.js From ff5ef9dc551cab0f3efdb7acf496366f691e47e5 Mon Sep 17 00:00:00 2001 From: timelyportfolio Date: Wed, 3 Aug 2016 17:07:41 -0500 Subject: [PATCH 2/9] add `in` \ `notin` and `within` \ `notwithin` filter transforms; register `filter` with plotly --- lib/filter.js | 9 + lib/index.js | 5 + src/transforms/filter.js | 33 +- src/transforms/groupby.js | 2 +- test/jasmine/tests/transforms_test.js | 489 +++++++++++++++++++++----- 5 files changed, 447 insertions(+), 91 deletions(-) create mode 100644 lib/filter.js diff --git a/lib/filter.js b/lib/filter.js new file mode 100644 index 00000000000..e7e4ecf078e --- /dev/null +++ b/lib/filter.js @@ -0,0 +1,9 @@ +/** +* Copyright 2012-2016, Plotly, Inc. +* All rights reserved. +* +* This source code is licensed under the MIT license found in the +* LICENSE file in the root directory of this source tree. +*/ + +module.exports = require('../src/transforms/filter'); diff --git a/lib/index.js b/lib/index.js index 4f37449c9c3..374dacc1681 100644 --- a/lib/index.js +++ b/lib/index.js @@ -29,4 +29,9 @@ Plotly.register([ require('./scattermapbox') ]); +// add transforms +Plotly.register([ + require('./filter') +]); + module.exports = Plotly; diff --git a/src/transforms/filter.js b/src/transforms/filter.js index 95215fc50cf..52ab62d4c00 100644 --- a/src/transforms/filter.js +++ b/src/transforms/filter.js @@ -1,11 +1,10 @@ 'use strict'; // var Lib = require('@src/lib'); -var Lib = require('../../../../src/lib'); +var Lib = require('../lib'); /*eslint no-unused-vars: 0*/ - // so that Plotly.register knows what to do with it exports.moduleType = 'transform'; @@ -16,11 +15,11 @@ exports.name = 'filter'; exports.attributes = { operation: { valType: 'enumerated', - values: ['=', '<', '>'], + values: ['=', '<', '>', 'within', 'notwithin', 'in', 'notin'], dflt: '=' }, value: { - valType: 'number', + valType: 'any', dflt: 0 }, filtersrc: { @@ -121,6 +120,16 @@ function transformOne(trace, state) { function getFilterFunc(opts) { var value = opts.value; + // if value is not array then coerce to + // an array of [value,value] so the + // filter function will work + // but perhaps should just error out + var value_arr = []; + if (!Array.isArray(value)) { + value_arr = [value, value]; + } else { + value_arr = value; + } switch(opts.operation) { case '=': @@ -129,6 +138,22 @@ function getFilterFunc(opts) { return function(v) { return v < value; }; case '>': return function(v) { return v > value; }; + case 'within': + return function(v) { + // keep the = ? + return v >= Math.min.apply( null, value ) && + v <= Math.max.apply( null, value ); + }; + case 'notwithin': + return function(v) { + // keep the = ? + return !(v >= Math.min.apply( null, value ) && + v <= Math.max.apply( null, value )); + }; + case 'in': + return function(v) { return value.indexOf(v) >= 0 }; + case 'notin': + return function(v) { return value.indexOf(v) === -1 }; } } diff --git a/src/transforms/groupby.js b/src/transforms/groupby.js index 41748a75c66..3a037922026 100644 --- a/src/transforms/groupby.js +++ b/src/transforms/groupby.js @@ -1,7 +1,7 @@ 'use strict'; // var Lib = require('@src/lib'); -var Lib = require('../../../../src/lib'); +var Lib = require('../lib'); /*eslint no-unused-vars: 0*/ diff --git a/test/jasmine/tests/transforms_test.js b/test/jasmine/tests/transforms_test.js index 1344518c8d7..68c07ca4f5b 100644 --- a/test/jasmine/tests/transforms_test.js +++ b/test/jasmine/tests/transforms_test.js @@ -7,8 +7,9 @@ var createGraphDiv = require('../assets/create_graph_div'); var destroyGraphDiv = require('../assets/destroy_graph_div'); Plotly.register([ - require('../assets/transforms/filter'), - require('../assets/transforms/groupby') + //register filter in build + //require('@src/transforms/filter'), + require('@src/transforms/groupby') ]); @@ -329,6 +330,406 @@ describe('one-to-one transforms:', function() { }); }); + + it('supplyTraceDefaults should supply the transform defaults', function() { + var traceIn = { + y: [2, 1, 2], + transforms: [{ type: 'filter' }] + }; + + var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + + expect(traceOut.transforms).toEqual([{ + type: 'filter', + operation: '=', + value: 0, + filtersrc: 'x' + }]); + }); + + it('supplyTraceDefaults should accept numeric as character', function() { + var traceIn = { + x: '1', + transforms: [{ + type: 'filter', + value: '0' + }] + }; + + var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + + expect(traceOut.transforms).toEqual([{ + type: 'filter', + operation: '=', + value: 0, + filtersrc: 'x' + }]); + + // should also convert if array + var traceIn = { + x: '1', + transforms: [{ + type: 'filter', + value: ['0'] + }] + }; + + var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + + expect(traceOut.transforms).toEqual([{ + type: 'filter', + operation: '=', + value: [0], + filtersrc: 'x' + }]); + }); + + it('supplyDataDefaults should apply the transform', function() { + var dataIn = [{ + x: [-2, -1, -2, 0, 1, 2, 3], + y: [1, 2, 3, 1, 2, 3, 1], + transforms: [{ + type: 'filter', + operation: '>', + value: 0, + filtersrc: 'x' + }] + }]; + + var dataOut = []; + Plots.supplyDataDefaults(dataIn, dataOut, {}, []); + + // does not mutate user data + expect(dataIn[0].x).toEqual([-2, -1, -2, 0, 1, 2, 3]); + expect(dataIn[0].y).toEqual([1, 2, 3, 1, 2, 3, 1]); + expect(dataIn[0].transforms).toEqual([{ + type: 'filter', + operation: '>', + value: 0, + filtersrc: 'x' + }]); + + // applies transform + expect(dataOut[0].x).toEqual([1, 2, 3]); + expect(dataOut[0].y).toEqual([2, 3, 1]); + + // TODO what is the expected behavior ??? +// expect(dataOut[0].transforms).toEqual([]); + + // keep ref to user data + expect(dataOut[0]._input.x).toEqual([-2, -1, -2, 0, 1, 2, 3]); + expect(dataOut[0]._input.y).toEqual([1, 2, 3, 1, 2, 3, 1]); + expect(dataOut[0]._input.transforms).toEqual([{ + type: 'filter', + operation: '>', + value: 0, + filtersrc: 'x' + }]); + + // keep ref to full transforms array + expect(dataOut[0]._fullInput.transforms).toEqual([{ + type: 'filter', + operation: '>', + value: 0, + filtersrc: 'x' + }]); + + // set index w.r.t. fullData + expect(dataOut[0].index).toEqual(0); + + // TODO do we really need this ??? + // set _index w.r.t. user data + expect(dataOut[0].index).toEqual(0); + }); + + it('filters should chain as AND', function(){ + var dataIn = [{ + x: [-2, -1, -2, 0, 1, 2, 3], + y: [1, 2, 3, 1, 2, 3, 1], + transforms: [ + { + type: 'filter', + operation: '>', + value: 0, + filtersrc: 'x' + }, + { + type: 'filter', + operation: '<', + value: 3, + filtersrc: 'x' + } + ] + }]; + + var dataOut = []; + Plots.supplyDataDefaults(dataIn, dataOut, {}, []); + + // applies transform + expect(dataOut[0].x).toEqual([1, 2]); + expect(dataOut[0].y).toEqual([2, 3]); + }); + + it('filters should handle range numeric values within and notwithin', function() { + var dataIn = [{ + x: [-2, -1, -2, 0, 1, 2, 3], + y: [1, 2, 3, 1, 2, 3, 1], + transforms: [{ + type: 'filter', + operation: 'within', + value: [-1, 1], + filtersrc: 'x' + }] + }]; + + var dataOut = []; + Plots.supplyDataDefaults(dataIn, dataOut, {}, []); + + // leave this section guarding against mutation + // for now but can probably eliminate later + // does not mutate user data + expect(dataIn[0].x).toEqual([-2, -1, -2, 0, 1, 2, 3]); + expect(dataIn[0].y).toEqual([1, 2, 3, 1, 2, 3, 1]); + expect(dataIn[0].transforms).toEqual([{ + type: 'filter', + operation: 'within', + value: [-1, 1], + filtersrc: 'x' + }]); + + // applies transform + expect(dataOut[0].x).toEqual([-1, 0, 1]); + expect(dataOut[0].y).toEqual([2, 1, 2]); + }); + + it('filters should ignore character values within and notwithin', function() { + var dataIn = [{ + x: ['a', 'b', 'c', 'd'], + y: [1, 2, 3, 4], + transforms: [{ + type: 'filter', + operation: 'within', + value: ['a', 'c'], + filtersrc: 'x' + }] + }]; + + var dataOut = []; + Plots.supplyDataDefaults(dataIn, dataOut, {}, []); + + // leave this section guarding against mutation + // for now but can probably eliminate later + // does not mutate user data + expect(dataIn[0].x).toEqual(['a', 'b', 'c', 'd']); + expect(dataIn[0].y).toEqual([1, 2, 3, 4]); + expect(dataIn[0].transforms).toEqual([{ + type: 'filter', + operation: 'within', + value: ['a', 'c'], + filtersrc: 'x' + }]); + + // applies transform + expect(dataOut[0].x).toEqual(['a', 'b', 'c', 'd']); + expect(dataOut[0].y).toEqual([1, 2, 3, 4]); + }); + + it('filters should handle numeric values in', function() { + var dataIn = [{ + x: [-2, -1, -2, 0, 1, 2, 3], + y: [1, 2, 3, 1, 2, 3, 1], + transforms: [{ + type: 'filter', + operation: 'in', + value: [-2, 0], + filtersrc: 'x' + }] + }]; + + var dataOut = []; + Plots.supplyDataDefaults(dataIn, dataOut, {}, []); + + // applies transform + expect(dataOut[0].x).toEqual([-2, -2, 0]); + expect(dataOut[0].y).toEqual([1, 3, 1]); + }); + + it('filters should handle numeric values in', function() { + var dataIn = [{ + x: [-2, -1, -2, 0, 1, 2, 3], + y: [1, 2, 3, 1, 2, 3, 1], + transforms: [{ + type: 'filter', + operation: 'notin', + value: [-2, 0], + filtersrc: 'x' + }] + }]; + + var dataOut = []; + Plots.supplyDataDefaults(dataIn, dataOut, {}, []); + + // applies transform + expect(dataOut[0].x).toEqual([-1, 1, 2, 3]); + expect(dataOut[0].y).toEqual([2, 2, 3, 1]); + }); + + + it('filters should handle strings with in', function() { + var dataIn = [{ + x: ['y', 't', 'b', 'm', 'p', 'l', 'o'], + y: [1, 2, 3, 1, 5, 10, 20], + transforms: [{ + type: 'filter', + operation: 'in', + value: ['p', 'l', 'o'], + filtersrc: 'x' + }] + }]; + + + var dataOut = []; + Plots.supplyDataDefaults(dataIn, dataOut, {}, []); + + // applies transform + expect(dataOut[0].x).toEqual(['p', 'l', 'o']); + expect(dataOut[0].y).toEqual([5, 10, 20]); + }); + + it('filters should handle strings with in', function() { + var dataIn = [{ + x: ['y', 't', 'b', 'm', 'p', 'l', 'o'], + y: [1, 2, 3, 1, 5, 10, 20], + transforms: [{ + type: 'filter', + operation: 'notin', + value: ['p', 'l', 'o'], + filtersrc: 'x' + }] + }]; + + + var dataOut = []; + Plots.supplyDataDefaults(dataIn, dataOut, {}, []); + + // applies transform + expect(dataOut[0].x).toEqual(['y', 't', 'b', 'm']); + expect(dataOut[0].y).toEqual([1, 2, 3, 1]); + }); + + + it('Plotly.plot should plot the transform trace', function(done) { + var data = Lib.extendDeep([], mockData0); + + Plotly.plot(createGraphDiv(), data).then(function(gd) { + assertDims([3]); + + var uid = data[0].uid; + expect(gd._fullData[0].uid).toEqual(uid + '0'); + + done(); + }); + }); + + it('Plotly.restyle should work', function(done) { + var data = Lib.extendDeep([], mockData0); + data[0].marker = { color: 'red' }; + + var gd = createGraphDiv(); + var dims = [3]; + + Plotly.plot(gd, data).then(function() { + expect(gd._fullData[0].marker.color).toEqual('red'); + assertStyle(dims, ['rgb(255, 0, 0)'], [1]); + + return Plotly.restyle(gd, 'marker.color', 'blue'); + }).then(function() { + expect(gd._fullData[0].marker.color).toEqual('blue'); + assertStyle(dims, ['rgb(0, 0, 255)'], [1]); + + return Plotly.restyle(gd, 'marker.color', 'red'); + }).then(function() { + expect(gd._fullData[0].marker.color).toEqual('red'); + assertStyle(dims, ['rgb(255, 0, 0)'], [1]); + + return Plotly.restyle(gd, 'transforms[0].value', 2.5); + }).then(function() { + assertStyle([1], ['rgb(255, 0, 0)'], [1]); + + done(); + }); + }); + + it('Plotly.extendTraces should work', function(done) { + var data = Lib.extendDeep([], mockData0); + + var gd = createGraphDiv(); + + Plotly.plot(gd, data).then(function() { + expect(gd.data[0].x.length).toEqual(7); + expect(gd._fullData[0].x.length).toEqual(3); + + assertDims([3]); + + return Plotly.extendTraces(gd, { + x: [ [-3, 4, 5] ], + y: [ [1, -2, 3] ] + }, [0]); + }).then(function() { + expect(gd.data[0].x.length).toEqual(10); + expect(gd._fullData[0].x.length).toEqual(5); + + assertDims([5]); + + done(); + }); + }); + + it('Plotly.deleteTraces should work', function(done) { + var data = Lib.extendDeep([], mockData1); + + var gd = createGraphDiv(); + + Plotly.plot(gd, data).then(function() { + assertDims([3, 4]); + + return Plotly.deleteTraces(gd, [1]); + }).then(function() { + assertDims([3]); + + return Plotly.deleteTraces(gd, [0]); + }).then(function() { + assertDims([]); + + done(); + }); + + }); + + it('toggling trace visibility should work', function(done) { + var data = Lib.extendDeep([], mockData1); + + var gd = createGraphDiv(); + + Plotly.plot(gd, data).then(function() { + assertDims([3, 4]); + + return Plotly.restyle(gd, 'visible', 'legendonly', [1]); + }).then(function() { + assertDims([3]); + + return Plotly.restyle(gd, 'visible', false, [0]); + }).then(function() { + assertDims([]); + + return Plotly.restyle(gd, 'visible', [true, true], [0, 1]); + }).then(function() { + assertDims([3, 4]); + + done(); + }); + }); + }); describe('one-to-many transforms:', function() { @@ -358,34 +759,6 @@ describe('one-to-many transforms:', function() { afterEach(destroyGraphDiv); - it('supplyDataDefaults should apply the transform while', function() { - var dummyTrace0 = { - x: [-2, -2, 1, 2, 3], - y: [1, 2, 2, 3, 1], - }; - - var dummyTrace1 = { - x: [-1, 2, 3], - y: [2, 3, 1], - }; - - var dataIn = [ - dummyTrace0, - Lib.extendDeep({}, mockData0[0]), - dummyTrace1, - Lib.extendDeep({}, mockData1[0]) - ]; - - var dataOut = []; - Plots.supplyDataDefaults(dataIn, dataOut, {}, []); - - expect(dataOut.map(function(trace) { return trace.index; })) - .toEqual([0, 1, 1, 2, 3, 3], 'setting index w.r.t user data'); - - expect(dataOut.map(function(trace) { return trace._expandedIndex; })) - .toEqual([0, 1, 2, 3, 4, 5], 'setting index w.r.t full data'); - }); - it('Plotly.plot should plot the transform traces', function(done) { var data = Lib.extendDeep([], mockData0); @@ -563,34 +936,6 @@ describe('multiple transforms:', function() { afterEach(destroyGraphDiv); - it('supplyDataDefaults should apply the transform while', function() { - var dummyTrace0 = { - x: [-2, -2, 1, 2, 3], - y: [1, 2, 2, 3, 1], - }; - - var dummyTrace1 = { - x: [-1, 2, 3], - y: [2, 3, 1], - }; - - var dataIn = [ - dummyTrace0, - Lib.extendDeep({}, mockData0[0]), - Lib.extendDeep({}, mockData1[0]), - dummyTrace1 - ]; - - var dataOut = []; - Plots.supplyDataDefaults(dataIn, dataOut, {}, []); - - expect(dataOut.map(function(trace) { return trace.index; })) - .toEqual([0, 1, 1, 2, 2, 3], 'setting index w.r.t user data'); - - expect(dataOut.map(function(trace) { return trace._expandedIndex; })) - .toEqual([0, 1, 2, 3, 4, 5], 'setting index w.r.t full data'); - }); - it('Plotly.plot should plot the transform traces', function(done) { var data = Lib.extendDeep([], mockData0); @@ -788,34 +1133,6 @@ describe('multiple traces with transforms:', function() { afterEach(destroyGraphDiv); - it('supplyDataDefaults should apply the transform while', function() { - var dummyTrace0 = { - x: [-2, -2, 1, 2, 3], - y: [1, 2, 2, 3, 1], - }; - - var dummyTrace1 = { - x: [-1, 2, 3], - y: [2, 3, 1], - }; - - var dataIn = [ - dummyTrace0, - Lib.extendDeep({}, mockData0[0]), - Lib.extendDeep({}, mockData0[1]), - dummyTrace1 - ]; - - var dataOut = []; - Plots.supplyDataDefaults(dataIn, dataOut, {}, []); - - expect(dataOut.map(function(trace) { return trace.index; })) - .toEqual([0, 1, 2, 2, 3], 'setting index w.r.t user data'); - - expect(dataOut.map(function(trace) { return trace._expandedIndex; })) - .toEqual([0, 1, 2, 3, 4], 'setting index w.r.t full data'); - }); - it('Plotly.plot should plot the transform traces', function(done) { var data = Lib.extendDeep([], mockData0); From f7fdd80bd441b09d8d4b0158252511dfd73582ce Mon Sep 17 00:00:00 2001 From: timelyportfolio Date: Thu, 4 Aug 2016 05:45:05 -0500 Subject: [PATCH 3/9] use value array for array comparisons and camelCase --- src/transforms/filter.js | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/transforms/filter.js b/src/transforms/filter.js index 52ab62d4c00..fa0a56d2eff 100644 --- a/src/transforms/filter.js +++ b/src/transforms/filter.js @@ -124,11 +124,11 @@ function getFilterFunc(opts) { // an array of [value,value] so the // filter function will work // but perhaps should just error out - var value_arr = []; + var valueArr = []; if (!Array.isArray(value)) { - value_arr = [value, value]; + valueArr = [value, value]; } else { - value_arr = value; + valueArr = value; } switch(opts.operation) { @@ -141,19 +141,19 @@ function getFilterFunc(opts) { case 'within': return function(v) { // keep the = ? - return v >= Math.min.apply( null, value ) && - v <= Math.max.apply( null, value ); + return v >= Math.min.apply( null, valueArr ) && + v <= Math.max.apply( null, valueArr ); }; case 'notwithin': return function(v) { // keep the = ? - return !(v >= Math.min.apply( null, value ) && - v <= Math.max.apply( null, value )); + return !(v >= Math.min.apply( null, valueArr ) && + v <= Math.max.apply( null, valueArr )); }; case 'in': - return function(v) { return value.indexOf(v) >= 0 }; + return function(v) { return valueArr.indexOf(v) >= 0 }; case 'notin': - return function(v) { return value.indexOf(v) === -1 }; + return function(v) { return valueArr.indexOf(v) === -1 }; } } From 6b85623a1aa0745588e09fa2e2d6bf35f61d6d4a Mon Sep 17 00:00:00 2001 From: timelyportfolio Date: Fri, 12 Aug 2016 08:07:01 -0500 Subject: [PATCH 4/9] accept '0' and ['0'] in filter --- src/transforms/filter.js | 12 +++++++++ test/jasmine/tests/transforms_test.js | 37 +++++++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/transforms/filter.js b/src/transforms/filter.js index fa0a56d2eff..ad6c547452e 100644 --- a/src/transforms/filter.js +++ b/src/transforms/filter.js @@ -1,5 +1,7 @@ 'use strict'; +var isNumeric = require('fast-isnumeric'); + // var Lib = require('@src/lib'); var Lib = require('../lib'); @@ -53,6 +55,16 @@ exports.supplyDefaults = function(transformIn, fullData, layout) { coerce('value'); coerce('filtersrc'); + // numeric values as character should be converted to numeric + if(Array.isArray(transformOut.value)) { + transformOut.value = transformOut.value.map(function(v) { + if(isNumeric(v)) v = +v; + return v; + }) + } else { + if(isNumeric(transformOut.value)) transformOut.value = +transformOut.value; + } + // or some more complex logic using fullData and layout return transformOut; diff --git a/test/jasmine/tests/transforms_test.js b/test/jasmine/tests/transforms_test.js index 68c07ca4f5b..0ac441bef29 100644 --- a/test/jasmine/tests/transforms_test.js +++ b/test/jasmine/tests/transforms_test.js @@ -384,6 +384,43 @@ describe('one-to-one transforms:', function() { }]); }); + it('supplyTraceDefaults should accept numeric as character', function() { + var traceIn = { + x: '1', + transforms: [{ + type: 'filter', + value: '0' + }] + }; + + var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + + expect(traceOut.transforms).toEqual([{ + type: 'filter', + operation: '=', + value: 0, + filtersrc: 'x' + }]); + + // should also convert if array + var traceIn = { + x: '1', + transforms: [{ + type: 'filter', + value: ['0'] + }] + }; + + var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + + expect(traceOut.transforms).toEqual([{ + type: 'filter', + operation: '=', + value: [0], + filtersrc: 'x' + }]); + }); + it('supplyDataDefaults should apply the transform', function() { var dataIn = [{ x: [-2, -1, -2, 0, 1, 2, 3], From 4fab5a5dffa3ab86865bbc62a03db5cb570c1567 Mon Sep 17 00:00:00 2001 From: timelyportfolio Date: Fri, 12 Aug 2016 08:52:13 -0500 Subject: [PATCH 5/9] ignore character values for `within` filter --- src/transforms/filter.js | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/transforms/filter.js b/src/transforms/filter.js index ad6c547452e..71527af39d7 100644 --- a/src/transforms/filter.js +++ b/src/transforms/filter.js @@ -152,6 +152,14 @@ function getFilterFunc(opts) { return function(v) { return v > value; }; case 'within': return function(v) { + // if character then ignore with no side effect + function notDateNumber(d){ + return !(isNumeric(d) || d instanceof Date); + } + if(valueArr.some(notDateNumber)) { + return true; + } + // keep the = ? return v >= Math.min.apply( null, valueArr ) && v <= Math.max.apply( null, valueArr ); From 5e010905478e56f016173708f6371e3e1ed9da45 Mon Sep 17 00:00:00 2001 From: timelyportfolio Date: Fri, 12 Aug 2016 10:03:11 -0500 Subject: [PATCH 6/9] use `Lib.isDateTime` --- src/transforms/filter.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/transforms/filter.js b/src/transforms/filter.js index 71527af39d7..d6aee799aa4 100644 --- a/src/transforms/filter.js +++ b/src/transforms/filter.js @@ -154,8 +154,8 @@ function getFilterFunc(opts) { return function(v) { // if character then ignore with no side effect function notDateNumber(d){ - return !(isNumeric(d) || d instanceof Date); - } + return !(isNumeric(d) || Lib.isDateTime(d)); + }; if(valueArr.some(notDateNumber)) { return true; } From 63fc097fc70ee9dba785da02b0739e3227af4581 Mon Sep 17 00:00:00 2001 From: timelyportfolio Date: Wed, 17 Aug 2016 09:16:54 -0500 Subject: [PATCH 7/9] clean and lint --- src/transforms/filter.js | 29 ++++++++----- test/jasmine/tests/transforms_test.js | 62 ++++++++++++++------------- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/transforms/filter.js b/src/transforms/filter.js index d6aee799aa4..2452b2722c4 100644 --- a/src/transforms/filter.js +++ b/src/transforms/filter.js @@ -1,3 +1,12 @@ +/** + * Copyright 2012-2016, Plotly, Inc. + * All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + + 'use strict'; var isNumeric = require('fast-isnumeric'); @@ -60,7 +69,7 @@ exports.supplyDefaults = function(transformIn, fullData, layout) { transformOut.value = transformOut.value.map(function(v) { if(isNumeric(v)) v = +v; return v; - }) + }); } else { if(isNumeric(transformOut.value)) transformOut.value = +transformOut.value; } @@ -137,7 +146,7 @@ function getFilterFunc(opts) { // filter function will work // but perhaps should just error out var valueArr = []; - if (!Array.isArray(value)) { + if(!Array.isArray(value)) { valueArr = [value, value]; } else { valueArr = value; @@ -153,27 +162,27 @@ function getFilterFunc(opts) { case 'within': return function(v) { // if character then ignore with no side effect - function notDateNumber(d){ + function notDateNumber(d) { return !(isNumeric(d) || Lib.isDateTime(d)); - }; + } if(valueArr.some(notDateNumber)) { return true; } // keep the = ? - return v >= Math.min.apply( null, valueArr ) && - v <= Math.max.apply( null, valueArr ); + return v >= Math.min.apply(null, valueArr) && + v <= Math.max.apply(null, valueArr); }; case 'notwithin': return function(v) { // keep the = ? - return !(v >= Math.min.apply( null, valueArr ) && - v <= Math.max.apply( null, valueArr )); + return !(v >= Math.min.apply(null, valueArr) && + v <= Math.max.apply(null, valueArr)); }; case 'in': - return function(v) { return valueArr.indexOf(v) >= 0 }; + return function(v) { return valueArr.indexOf(v) >= 0; }; case 'notin': - return function(v) { return valueArr.indexOf(v) === -1 }; + return function(v) { return valueArr.indexOf(v) === -1; }; } } diff --git a/test/jasmine/tests/transforms_test.js b/test/jasmine/tests/transforms_test.js index 0ac441bef29..0925cd39914 100644 --- a/test/jasmine/tests/transforms_test.js +++ b/test/jasmine/tests/transforms_test.js @@ -35,15 +35,17 @@ describe('one-to-one transforms:', function() { }] }]; + var traceIn, traceOut; + afterEach(destroyGraphDiv); it('supplyTraceDefaults should supply the transform defaults', function() { - var traceIn = { + traceIn = { y: [2, 1, 2], transforms: [{ type: 'filter' }] }; - var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); expect(traceOut.transforms).toEqual([{ type: 'filter', @@ -54,18 +56,18 @@ describe('one-to-one transforms:', function() { }); it('supplyTraceDefaults should not bail if transform module is not found', function() { - var traceIn = { + traceIn = { y: [2, 1, 2], transforms: [{ type: 'invalid' }] }; - var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); expect(traceOut.y).toBe(traceIn.y); }); it('supplyTraceDefaults should honored global transforms', function() { - var traceIn = { + traceIn = { y: [2, 1, 2], transforms: [{ type: 'filter', @@ -81,7 +83,7 @@ describe('one-to-one transforms:', function() { }] }; - var traceOut = Plots.supplyTraceDefaults(traceIn, 0, layout); + traceOut = Plots.supplyTraceDefaults(traceIn, 0, layout); expect(traceOut.transforms[0]).toEqual({ type: 'filter', @@ -140,7 +142,7 @@ describe('one-to-one transforms:', function() { it('supplyDataDefaults should apply the transform while', function() { var dataIn = [{ x: [-2, -2, 1, 2, 3], - y: [1, 2, 2, 3, 1], + y: [1, 2, 2, 3, 1] }, { x: [-2, -1, -2, 0, 1, 2, 3], y: [1, 2, 3, 1, 2, 3, 1], @@ -332,12 +334,12 @@ describe('one-to-one transforms:', function() { it('supplyTraceDefaults should supply the transform defaults', function() { - var traceIn = { + traceIn = { y: [2, 1, 2], transforms: [{ type: 'filter' }] }; - var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); expect(traceOut.transforms).toEqual([{ type: 'filter', @@ -348,7 +350,7 @@ describe('one-to-one transforms:', function() { }); it('supplyTraceDefaults should accept numeric as character', function() { - var traceIn = { + traceIn = { x: '1', transforms: [{ type: 'filter', @@ -356,7 +358,7 @@ describe('one-to-one transforms:', function() { }] }; - var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); expect(traceOut.transforms).toEqual([{ type: 'filter', @@ -366,7 +368,7 @@ describe('one-to-one transforms:', function() { }]); // should also convert if array - var traceIn = { + traceIn = { x: '1', transforms: [{ type: 'filter', @@ -374,7 +376,7 @@ describe('one-to-one transforms:', function() { }] }; - var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); expect(traceOut.transforms).toEqual([{ type: 'filter', @@ -385,7 +387,7 @@ describe('one-to-one transforms:', function() { }); it('supplyTraceDefaults should accept numeric as character', function() { - var traceIn = { + traceIn = { x: '1', transforms: [{ type: 'filter', @@ -393,7 +395,7 @@ describe('one-to-one transforms:', function() { }] }; - var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); expect(traceOut.transforms).toEqual([{ type: 'filter', @@ -403,7 +405,7 @@ describe('one-to-one transforms:', function() { }]); // should also convert if array - var traceIn = { + traceIn = { x: '1', transforms: [{ type: 'filter', @@ -411,7 +413,7 @@ describe('one-to-one transforms:', function() { }] }; - var traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); + traceOut = Plots.supplyTraceDefaults(traceIn, 0, {}); expect(traceOut.transforms).toEqual([{ type: 'filter', @@ -479,23 +481,23 @@ describe('one-to-one transforms:', function() { expect(dataOut[0].index).toEqual(0); }); - it('filters should chain as AND', function(){ + it('filters should chain as AND', function() { var dataIn = [{ x: [-2, -1, -2, 0, 1, 2, 3], y: [1, 2, 3, 1, 2, 3, 1], transforms: [ - { - type: 'filter', - operation: '>', - value: 0, - filtersrc: 'x' - }, - { - type: 'filter', - operation: '<', - value: 3, - filtersrc: 'x' - } + { + type: 'filter', + operation: '>', + value: 0, + filtersrc: 'x' + }, + { + type: 'filter', + operation: '<', + value: 3, + filtersrc: 'x' + } ] }]; From 446f32d43e9d5186ec95d2a5b146e05306c77989 Mon Sep 17 00:00:00 2001 From: timelyportfolio Date: Wed, 17 Aug 2016 09:35:16 -0500 Subject: [PATCH 8/9] remove filter register in validate_test --- test/jasmine/tests/validate_test.js | 6 ------ 1 file changed, 6 deletions(-) diff --git a/test/jasmine/tests/validate_test.js b/test/jasmine/tests/validate_test.js index 8a55323a6bd..40220481f7e 100644 --- a/test/jasmine/tests/validate_test.js +++ b/test/jasmine/tests/validate_test.js @@ -1,12 +1,6 @@ var Plotly = require('@lib/index'); var Lib = require('@src/lib'); -Plotly.register([ - // until they become official - require('../assets/transforms/filter') -]); - - describe('Plotly.validate', function() { function assertErrorContent(obj, code, cont, trace, path, astr, msg) { From 9b65721f645c3fd1a9c17c0ceca7a9c29234e30a Mon Sep 17 00:00:00 2001 From: timelyportfolio Date: Wed, 17 Aug 2016 09:36:54 -0500 Subject: [PATCH 9/9] try to get header correct --- src/transforms/filter.js | 1 - src/transforms/groupby.js | 8 ++++++++ 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/src/transforms/filter.js b/src/transforms/filter.js index 2452b2722c4..d0ea26f5de8 100644 --- a/src/transforms/filter.js +++ b/src/transforms/filter.js @@ -6,7 +6,6 @@ * LICENSE file in the root directory of this source tree. */ - 'use strict'; var isNumeric = require('fast-isnumeric'); diff --git a/src/transforms/groupby.js b/src/transforms/groupby.js index 3a037922026..a1d70782df5 100644 --- a/src/transforms/groupby.js +++ b/src/transforms/groupby.js @@ -1,3 +1,11 @@ +/** + * Copyright 2012-2016, Plotly, Inc. + * All rights reserved. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + 'use strict'; // var Lib = require('@src/lib');