1010
1111var Lib = require ( '../lib' ) ;
1212var axisIds = require ( '../plots/cartesian/axis_ids' ) ;
13+ var autoType = require ( '../plots/cartesian/axis_autotype' ) ;
14+ var setConvert = require ( '../plots/cartesian/set_convert' ) ;
1315
1416var INEQUALITY_OPS = [ '=' , '<' , '>=' , '>' , '<=' ] ;
1517var INTERVAL_OPS = [ '[]' , '()' , '[)' , '(]' , '][' , ')(' , '](' , ')[' ] ;
@@ -27,18 +29,22 @@ exports.attributes = {
2729 'Determines whether this filter transform is enabled or disabled.'
2830 ] . join ( ' ' )
2931 } ,
30- filtersrc : {
32+ target : {
3133 valType : 'string' ,
3234 strict : true ,
3335 noBlank : true ,
36+ arrayOk : true ,
3437 dflt : 'x' ,
3538 description : [
36- 'Sets the variable in the parent trace object' ,
37- 'by which the filter will be applied.' ,
39+ 'Sets the filter target by which the filter is applied.' ,
3840
41+ 'If a string, *target* is assumed to be a reference to a data array' ,
42+ 'in the parent trace object.' ,
3943 'To filter about nested variables, use *.* to access them.' ,
40- 'For example, set `filtersrc` to *marker.color* to filter' ,
41- 'about the marker color array.'
44+ 'For example, set `target` to *marker.color* to filter' ,
45+ 'about the marker color array.' ,
46+
47+ 'If an array, *target* is then the data array by which the filter is applied.'
4248 ] . join ( ' ' )
4349 } ,
4450 operation : {
@@ -77,7 +83,7 @@ exports.attributes = {
7783 'Sets the value or values by which to filter by.' ,
7884
7985 'Values are expected to be in the same type as the data linked' ,
80- 'to *filtersrc *.' ,
86+ 'to *target *.' ,
8187
8288 'When `operation` is set to one of the inequality values' ,
8389 '(' + INEQUALITY_OPS + ')' ,
@@ -108,25 +114,24 @@ exports.supplyDefaults = function(transformIn) {
108114 if ( enabled ) {
109115 coerce ( 'operation' ) ;
110116 coerce ( 'value' ) ;
111- coerce ( 'filtersrc ' ) ;
117+ coerce ( 'target ' ) ;
112118 }
113119
114120 return transformOut ;
115121} ;
116122
117123exports . calcTransform = function ( gd , trace , opts ) {
118- var filtersrc = opts . filtersrc ,
119- filtersrcOk = filtersrc && Array . isArray ( Lib . nestedProperty ( trace , filtersrc ) . get ( ) ) ;
120-
121- if ( ! opts . enabled || ! filtersrcOk ) return ;
124+ if ( ! opts . enabled ) return ;
122125
123- var dataToCoord = getDataToCoordFunc ( gd , trace , filtersrc ) ,
124- filterFunc = getFilterFunc ( opts , dataToCoord ) ;
126+ var target = opts . target ,
127+ filterArray = getFilterArray ( trace , target ) ,
128+ len = filterArray . length ;
125129
126- var filterArr = Lib . nestedProperty ( trace , filtersrc ) . get ( ) ,
127- len = filterArr . length ;
130+ if ( ! len ) return ;
128131
129- var arrayAttrs = Lib . findArrayAttributes ( trace ) ,
132+ var dataToCoord = getDataToCoordFunc ( gd , trace , target ) ,
133+ filterFunc = getFilterFunc ( opts , dataToCoord ) ,
134+ arrayAttrs = Lib . findArrayAttributes ( trace ) ,
130135 originalArrays = { } ;
131136
132137 // copy all original array attribute values,
@@ -147,7 +152,7 @@ exports.calcTransform = function(gd, trace, opts) {
147152 }
148153
149154 for ( var i = 0 ; i < len ; i ++ ) {
150- var v = filterArr [ i ] ;
155+ var v = filterArray [ i ] ;
151156
152157 if ( ! filterFunc ( v ) ) continue ;
153158
@@ -157,18 +162,43 @@ exports.calcTransform = function(gd, trace, opts) {
157162 }
158163} ;
159164
160- function getDataToCoordFunc ( gd , trace , filtersrc ) {
161- var ax = axisIds . getFromTrace ( gd , trace , filtersrc ) ;
165+ function getFilterArray ( trace , target ) {
166+ if ( typeof target === 'string' && target ) {
167+ var array = Lib . nestedProperty ( trace , target ) . get ( ) ;
168+
169+ return Array . isArray ( array ) ? array : [ ] ;
170+ }
171+ else if ( Array . isArray ( target ) ) return target . slice ( ) ;
172+
173+ return false ;
174+ }
175+
176+ function getDataToCoordFunc ( gd , trace , target ) {
177+ var ax ;
178+
179+ // In the case of an array target, make a mock data array
180+ // and call supplyDefaults to the data type and
181+ // setup the data-to-calc method.
182+ if ( Array . isArray ( target ) ) {
183+ ax = {
184+ type : autoType ( target ) ,
185+ _categories : [ ]
186+ } ;
187+ setConvert ( ax ) ;
188+ }
189+ else {
190+ ax = axisIds . getFromTrace ( gd , trace , target ) ;
191+ }
162192
163- // if 'filtersrc ' has corresponding axis
193+ // if 'target ' has corresponding axis
164194 // -> use setConvert method
165195 if ( ax ) return ax . d2c ;
166196
167197 // special case for 'ids'
168198 // -> cast to String
169- if ( filtersrc === 'ids' ) return function ( v ) { return String ( v ) ; } ;
199+ if ( target === 'ids' ) return function ( v ) { return String ( v ) ; } ;
170200
171- // otherwise
201+ // otherwise (e.g. numeric-array of 'marker.color' or 'marker.size')
172202 // -> cast to Number
173203 return function ( v ) { return + v ; } ;
174204}
0 commit comments