@@ -358,6 +358,7 @@ function prepSelect(e, startX, startY, dragOptions, mode) {
358
358
// ----------------
359
359
// TODO handle clearing selection when no point is clicked (based on hoverData)
360
360
// TODO do we have to consider multiple traces?
361
+ // TODO implement selection retention (Shift key) for lasso and box
361
362
function selectOnClick ( gd , numClicks , evt ) {
362
363
var calcData = gd . calcdata [ 0 ] ;
363
364
@@ -368,28 +369,42 @@ function selectOnClick(gd, numClicks, evt) {
368
369
var selectPreconditionsMet = isHoverDataSet && isSingleClick ;
369
370
370
371
if ( selectPreconditionsMet ) {
371
- var trace = calcData [ 0 ] . trace ;
372
- var hoverDatum = hoverData [ 0 ] ;
373
-
374
- var retainCurrentSelection = evt . shiftKey ;
375
- var pointAlreadySelected = isPointAlreadySelected ( trace , hoverDatum . pointNumber ) ;
376
- var traceSelection = pointAlreadySelected ?
377
- trace . _module . deselectPoint ( calcData , hoverDatum , retainCurrentSelection ) :
378
- trace . _module . selectPoint ( calcData , hoverDatum , retainCurrentSelection ) ;
372
+ var trace = calcData [ 0 ] . trace ,
373
+ hoverDatum = hoverData [ 0 ] ,
374
+ module = trace . _module ;
375
+
376
+ // Execute selection by delegating to respective module
377
+ var retainSelection = evt . shiftKey ,
378
+ pointSelected = isPointSelected ( trace , hoverDatum . pointNumber ) ,
379
+ onePointSelectedOnly = isOnePointSelectedOnly ( trace ) ;
380
+
381
+ var shouldDeselectPoint = ( pointSelected && onePointSelectedOnly ) ||
382
+ ( pointSelected && ! onePointSelectedOnly && retainSelection ) ;
383
+
384
+ var newTraceSelection = shouldDeselectPoint ?
385
+ module . deselectPoint ( calcData , hoverDatum , retainSelection ) :
386
+ module . selectPoint ( calcData , hoverDatum , retainSelection ) ;
387
+
388
+ // Update selection state
379
389
var searchInfo =
380
- _createSearchInfo ( trace . _module , calcData , hoverDatum . xaxis , hoverDatum . yaxis ) ;
381
- var selection = fillSelectionItem ( traceSelection , searchInfo ) ;
390
+ _createSearchInfo ( module , calcData , hoverDatum . xaxis , hoverDatum . yaxis ) ;
391
+ var selection = fillSelectionItem ( newTraceSelection , searchInfo ) ;
382
392
var eventData = { points : selection } ;
383
393
384
394
updateSelectedState ( gd , [ searchInfo ] , eventData ) ;
385
395
}
386
396
}
387
397
388
- function isPointAlreadySelected ( trace , pointNumber ) {
398
+ function isPointSelected ( trace , pointNumber ) {
389
399
if ( ! trace . selectedpoints && ! Array . isArray ( trace . selectedpoints ) ) return false ;
390
400
return trace . selectedpoints . indexOf ( pointNumber ) > - 1 ;
391
401
}
392
402
403
+ function isOnePointSelectedOnly ( trace ) {
404
+ if ( ! trace . selectedpoints && ! Array . isArray ( trace . selectedpoints ) ) return false ;
405
+ return trace . selectedpoints . length === 1 ;
406
+ }
407
+
393
408
// TODO Consider using in other places around here as well
394
409
function _createSearchInfo ( module , calcData , xaxis , yaxis ) {
395
410
return {
0 commit comments