@@ -16,7 +16,6 @@ var Color = require('../../components/color');
1616var Fx = require ( '../../components/fx' ) ;
1717
1818var polygon = require ( '../../lib/polygon' ) ;
19- var select = require ( '../../lib/select' ) ;
2019var throttle = require ( '../../lib/throttle' ) ;
2120var makeEventData = require ( '../../components/fx/helpers' ) . makeEventData ;
2221var getFromId = require ( './axis_ids' ) . getFromId ;
@@ -27,8 +26,6 @@ var MINSELECT = constants.MINSELECT;
2726
2827var filteredPolygon = polygon . filter ;
2928var polygonTester = polygon . tester ;
30- var pointSelectionDef = select . pointSelectionDef ;
31- var multiTester = select . multiTester ;
3229
3330function getAxId ( ax ) { return ax . _id ; }
3431
@@ -330,7 +327,7 @@ function selectOnClick(evt, gd, xAxes, yAxes, subplot, dragOptions, polygonOutli
330327 ( pointOrBinSelected !== undefined ?
331328 pointOrBinSelected :
332329 isPointOrBinSelected ( clickedPtInfo ) ) ;
333- currentSelectionDef = pointSelectionDef ( clickedPtInfo . pointNumber , clickedPtInfo . searchInfo , subtract ) ;
330+ currentSelectionDef = newPointSelectionDef ( clickedPtInfo . pointNumber , clickedPtInfo . searchInfo , subtract ) ;
334331
335332 var allSelectionDefs = dragOptions . selectionDefs . concat ( [ currentSelectionDef ] ) ;
336333 selectionTester = multiTester ( allSelectionDefs ) ;
@@ -363,6 +360,107 @@ function selectOnClick(evt, gd, xAxes, yAxes, subplot, dragOptions, polygonOutli
363360 }
364361}
365362
363+ /**
364+ * Constructs a new point selection definition object.
365+ */
366+ function newPointSelectionDef ( pointNumber , searchInfo , subtract ) {
367+ return {
368+ pointNumber : pointNumber ,
369+ searchInfo : searchInfo ,
370+ subtract : subtract
371+ } ;
372+ }
373+
374+ function isPointSelectionDef ( o ) {
375+ return 'pointNumber' in o && 'searchInfo' in o ;
376+ }
377+
378+ /*
379+ * Constructs a new point number tester.
380+ */
381+ function newPointNumTester ( pointSelectionDef ) {
382+ return {
383+ xmin : 0 ,
384+ xmax : 0 ,
385+ ymin : 0 ,
386+ ymax : 0 ,
387+ pts : [ ] ,
388+ contains : function ( pt , omitFirstEdge , pointNumber , searchInfo ) {
389+ var idxWantedTrace = pointSelectionDef . searchInfo . cd [ 0 ] . trace . _expandedIndex ;
390+ var idxActualTrace = searchInfo . cd [ 0 ] . trace . _expandedIndex ;
391+ return idxActualTrace === idxWantedTrace &&
392+ pointNumber === pointSelectionDef . pointNumber ;
393+ } ,
394+ isRect : false ,
395+ degenerate : false ,
396+ subtract : pointSelectionDef . subtract
397+ } ;
398+ }
399+
400+ /**
401+ * Wraps multiple selection testers.
402+ *
403+ * @param {Array } list - An array of selection testers.
404+ *
405+ * @return a selection tester object with a contains function
406+ * that can be called to evaluate a point against all wrapped
407+ * selection testers that were passed in list.
408+ */
409+ function multiTester ( list ) {
410+ var testers = [ ] ;
411+ var xmin = isPointSelectionDef ( list [ 0 ] ) ? 0 : list [ 0 ] [ 0 ] [ 0 ] ;
412+ var xmax = xmin ;
413+ var ymin = isPointSelectionDef ( list [ 0 ] ) ? 0 : list [ 0 ] [ 0 ] [ 1 ] ;
414+ var ymax = ymin ;
415+
416+ for ( var i = 0 ; i < list . length ; i ++ ) {
417+ if ( isPointSelectionDef ( list [ i ] ) ) {
418+ testers . push ( newPointNumTester ( list [ i ] ) ) ;
419+ } else {
420+ var tester = polygon . tester ( list [ i ] ) ;
421+ tester . subtract = list [ i ] . subtract ;
422+ testers . push ( tester ) ;
423+ xmin = Math . min ( xmin , tester . xmin ) ;
424+ xmax = Math . max ( xmax , tester . xmax ) ;
425+ ymin = Math . min ( ymin , tester . ymin ) ;
426+ ymax = Math . max ( ymax , tester . ymax ) ;
427+ }
428+ }
429+
430+ /**
431+ * Tests if the given point is within this tester.
432+ *
433+ * @param {Array } pt - [0] is the x coordinate, [1] is the y coordinate of the point.
434+ * @param {* } arg - An optional parameter to pass down to wrapped testers.
435+ * @param {number } pointNumber - The point number of the point within the underlying data array.
436+ * @param {number } searchInfo - An object identifying the trace the point is contained in.
437+ *
438+ * @return {boolean } true if point is considered to be selected, false otherwise.
439+ */
440+ function contains ( pt , arg , pointNumber , searchInfo ) {
441+ var contained = false ;
442+ for ( var i = 0 ; i < testers . length ; i ++ ) {
443+ if ( testers [ i ] . contains ( pt , arg , pointNumber , searchInfo ) ) {
444+ // if contained by subtract tester - exclude the point
445+ contained = testers [ i ] . subtract === false ;
446+ }
447+ }
448+
449+ return contained ;
450+ }
451+
452+ return {
453+ xmin : xmin ,
454+ xmax : xmax ,
455+ ymin : ymin ,
456+ ymax : ymax ,
457+ pts : [ ] ,
458+ contains : contains ,
459+ isRect : false ,
460+ degenerate : false
461+ } ;
462+ }
463+
366464function coerceSelectionsCache ( evt , gd , dragOptions ) {
367465 var fullLayout = gd . _fullLayout ;
368466 var zoomLayer = fullLayout . _zoomlayer ;
0 commit comments