@@ -22,6 +22,7 @@ var svgTextUtils = require('../../lib/svg_text_utils');
22
22
var xmlnsNamespaces = require ( '../../constants/xmlns_namespaces' ) ;
23
23
var alignment = require ( '../../constants/alignment' ) ;
24
24
var LINE_SPACING = alignment . LINE_SPACING ;
25
+ var DESELECTDIM = require ( '../../constants/interactions' ) . DESELECTDIM ;
25
26
26
27
var subTypes = require ( '../../traces/scatter/subtypes' ) ;
27
28
var makeBubbleSizeFn = require ( '../../traces/scatter/make_bubble_size_func' ) ;
@@ -92,21 +93,27 @@ drawing.translatePoints = function(s, xa, ya) {
92
93
} ) ;
93
94
} ;
94
95
95
- drawing . hideOutsideRangePoint = function ( d , sel , xa , ya ) {
96
+ drawing . hideOutsideRangePoint = function ( d , sel , xa , ya , xcalendar , ycalendar ) {
96
97
sel . attr (
97
98
'display' ,
98
- xa . isPtWithinRange ( d ) && ya . isPtWithinRange ( d ) ? null : 'none'
99
+ ( xa . isPtWithinRange ( d , xcalendar ) && ya . isPtWithinRange ( d , ycalendar ) ) ? null : 'none'
99
100
) ;
100
101
} ;
101
102
102
- drawing . hideOutsideRangePoints = function ( points , subplot ) {
103
+ drawing . hideOutsideRangePoints = function ( traceGroups , subplot ) {
103
104
if ( ! subplot . _hasClipOnAxisFalse ) return ;
104
105
105
106
var xa = subplot . xaxis ;
106
107
var ya = subplot . yaxis ;
107
108
108
- points . each ( function ( d ) {
109
- drawing . hideOutsideRangePoint ( d , d3 . select ( this ) , xa , ya ) ;
109
+ traceGroups . each ( function ( d ) {
110
+ var trace = d [ 0 ] . trace ;
111
+ var xcalendar = trace . xcalendar ;
112
+ var ycalendar = trace . ycalendar ;
113
+
114
+ traceGroups . selectAll ( '.point,.textpoint' ) . each ( function ( d ) {
115
+ drawing . hideOutsideRangePoint ( d , d3 . select ( this ) , xa , ya , xcalendar , ycalendar ) ;
116
+ } ) ;
110
117
} ) ;
111
118
} ;
112
119
@@ -247,18 +254,22 @@ drawing.symbolNumber = function(v) {
247
254
return Math . floor ( Math . max ( v , 0 ) ) ;
248
255
} ;
249
256
257
+ function makePointPath ( symbolNumber , r ) {
258
+ var base = symbolNumber % 100 ;
259
+ return drawing . symbolFuncs [ base ] ( r ) + ( symbolNumber >= 200 ? DOTPATH : '' ) ;
260
+ }
261
+
250
262
function singlePointStyle ( d , sel , trace , markerScale , lineScale , marker , markerLine , gd ) {
251
- // only scatter & box plots get marker path and opacity
252
- // bars, histograms don't
253
263
if ( Registry . traceIs ( trace , 'symbols' ) ) {
254
264
var sizeFn = makeBubbleSizeFn ( trace ) ;
255
265
256
266
sel . attr ( 'd' , function ( d ) {
257
267
var r ;
258
268
259
269
// handle multi-trace graph edit case
260
- if ( d . ms === 'various' || marker . size === 'various' ) r = 3 ;
261
- else {
270
+ if ( d . ms === 'various' || marker . size === 'various' ) {
271
+ r = 3 ;
272
+ } else {
262
273
r = subTypes . isBubble ( trace ) ?
263
274
sizeFn ( d . ms ) : ( marker . size || 6 ) / 2 ;
264
275
}
@@ -267,21 +278,20 @@ function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerL
267
278
d . mrc = r ;
268
279
269
280
// turn the symbol into a sanitized number
270
- var x = drawing . symbolNumber ( d . mx || marker . symbol ) || 0 ,
271
- xBase = x % 100 ;
281
+ var x = drawing . symbolNumber ( d . mx || marker . symbol ) || 0 ;
272
282
273
283
// save if this marker is open
274
284
// because that impacts how to handle colors
275
285
d . om = x % 200 >= 100 ;
276
286
277
- return drawing . symbolFuncs [ xBase ] ( r ) +
278
- ( x >= 200 ? DOTPATH : '' ) ;
279
- } )
280
- . style ( 'opacity' , function ( d ) {
281
- return ( d . mo + 1 || marker . opacity + 1 ) - 1 ;
287
+ return makePointPath ( x , r ) ;
282
288
} ) ;
283
289
}
284
290
291
+ sel . style ( 'opacity' , function ( d ) {
292
+ return ( d . mo + 1 || marker . opacity + 1 ) - 1 ;
293
+ } ) ;
294
+
285
295
var perPointGradient = false ;
286
296
287
297
// 'so' is suspected outliers, for box plots
@@ -409,7 +419,6 @@ drawing.singlePointStyle = function(d, sel, trace, markerScale, lineScale, gd) {
409
419
var marker = trace . marker ;
410
420
411
421
singlePointStyle ( d , sel , trace , markerScale , lineScale , marker , marker . line , gd ) ;
412
-
413
422
} ;
414
423
415
424
drawing . pointStyle = function ( s , trace , gd ) {
@@ -426,6 +435,84 @@ drawing.pointStyle = function(s, trace, gd) {
426
435
} ) ;
427
436
} ;
428
437
438
+ drawing . selectedPointStyle = function ( s , trace ) {
439
+ if ( ! s . size ( ) || ! trace . selectedpoints ) return ;
440
+
441
+ var selectedAttrs = trace . selected || { } ;
442
+ var unselectedAttrs = trace . unselected || { } ;
443
+
444
+ var marker = trace . marker || { } ;
445
+ var selectedMarker = selectedAttrs . marker || { } ;
446
+ var unselectedMarker = unselectedAttrs . marker || { } ;
447
+
448
+ var mo = marker . opacity ;
449
+ var smo = selectedMarker . opacity ;
450
+ var usmo = unselectedMarker . opacity ;
451
+ var smoIsDefined = smo !== undefined ;
452
+ var usmoIsDefined = usmo !== undefined ;
453
+
454
+ s . each ( function ( d ) {
455
+ var pt = d3 . select ( this ) ;
456
+ var dmo = d . mo ;
457
+ var dmoIsDefined = dmo !== undefined ;
458
+ var mo2 ;
459
+
460
+ if ( dmoIsDefined || smoIsDefined || usmoIsDefined ) {
461
+ if ( d . selected ) {
462
+ if ( smoIsDefined ) mo2 = smo ;
463
+ } else {
464
+ if ( usmoIsDefined ) mo2 = usmo ;
465
+ else mo2 = DESELECTDIM * ( dmoIsDefined ? dmo : mo ) ;
466
+ }
467
+ }
468
+
469
+ if ( mo2 !== undefined ) pt . style ( 'opacity' , mo2 ) ;
470
+ } ) ;
471
+
472
+ var smc = selectedMarker . color ;
473
+ var usmc = unselectedMarker . color ;
474
+
475
+ if ( smc || usmc ) {
476
+ s . each ( function ( d ) {
477
+ var pt = d3 . select ( this ) ;
478
+ var mc2 ;
479
+
480
+ if ( d . selected ) {
481
+ if ( smc ) mc2 = smc ;
482
+ } else {
483
+ if ( usmc ) mc2 = usmc ;
484
+ }
485
+
486
+ if ( mc2 ) Color . fill ( pt , mc2 ) ;
487
+ } ) ;
488
+ }
489
+
490
+ var sms = selectedMarker . size ;
491
+ var usms = unselectedMarker . size ;
492
+ var smsIsDefined = sms !== undefined ;
493
+ var usmsIsDefined = usms !== undefined ;
494
+
495
+ if ( Registry . traceIs ( trace , 'symbols' ) && ( smsIsDefined || usmsIsDefined ) ) {
496
+ s . each ( function ( d ) {
497
+ var pt = d3 . select ( this ) ;
498
+ var mrc = d . mrc ;
499
+ var mx = d . mx || marker . symbol || 0 ;
500
+ var mrc2 ;
501
+
502
+ if ( d . selected ) {
503
+ mrc2 = ( smsIsDefined ) ? sms / 2 : mrc ;
504
+ } else {
505
+ mrc2 = ( usmsIsDefined ) ? usms / 2 : mrc ;
506
+ }
507
+
508
+ pt . attr ( 'd' , makePointPath ( drawing . symbolNumber ( mx ) , mrc2 ) ) ;
509
+
510
+ // save for selectedTextStyle
511
+ d . mrc2 = mrc2 ;
512
+ } ) ;
513
+ }
514
+ } ;
515
+
429
516
drawing . tryColorscale = function ( marker , prefix ) {
430
517
var cont = prefix ? Lib . nestedProperty ( marker , prefix ) . get ( ) : marker ,
431
518
scl = cont . colorscale ,
@@ -439,8 +526,39 @@ drawing.tryColorscale = function(marker, prefix) {
439
526
else return Lib . identity ;
440
527
} ;
441
528
442
- // draw text at points
443
529
var TEXTOFFSETSIGN = { start : 1 , end : - 1 , middle : 0 , bottom : 1 , top : - 1 } ;
530
+
531
+ function textPointPosition ( s , textPosition , fontSize , markerRadius ) {
532
+ var group = d3 . select ( s . node ( ) . parentNode ) ;
533
+
534
+ var v = textPosition . indexOf ( 'top' ) !== - 1 ?
535
+ 'top' :
536
+ textPosition . indexOf ( 'bottom' ) !== - 1 ? 'bottom' : 'middle' ;
537
+ var h = textPosition . indexOf ( 'left' ) !== - 1 ?
538
+ 'end' :
539
+ textPosition . indexOf ( 'right' ) !== - 1 ? 'start' : 'middle' ;
540
+
541
+ // if markers are shown, offset a little more than
542
+ // the nominal marker size
543
+ // ie 2/1.6 * nominal, bcs some markers are a bit bigger
544
+ var r = markerRadius ? markerRadius / 0.8 + 1 : 0 ;
545
+
546
+ var numLines = ( svgTextUtils . lineCount ( s ) - 1 ) * LINE_SPACING + 1 ;
547
+ var dx = TEXTOFFSETSIGN [ h ] * r ;
548
+ var dy = fontSize * 0.75 + TEXTOFFSETSIGN [ v ] * r +
549
+ ( TEXTOFFSETSIGN [ v ] - 1 ) * numLines * fontSize / 2 ;
550
+
551
+ // fix the overall text group position
552
+ s . attr ( 'text-anchor' , h ) ;
553
+ group . attr ( 'transform' , 'translate(' + dx + ',' + dy + ')' ) ;
554
+ }
555
+
556
+ function extracTextFontSize ( d , trace ) {
557
+ var fontSize = d . ts || trace . textfont . size ;
558
+ return ( isNumeric ( fontSize ) && fontSize > 0 ) ? fontSize : 0 ;
559
+ }
560
+
561
+ // draw text at points
444
562
drawing . textPointStyle = function ( s , trace , gd ) {
445
563
s . each ( function ( d ) {
446
564
var p = d3 . select ( this ) ;
@@ -451,35 +569,43 @@ drawing.textPointStyle = function(s, trace, gd) {
451
569
return ;
452
570
}
453
571
454
- var pos = d . tp || trace . textposition ,
455
- v = pos . indexOf ( 'top' ) !== - 1 ? 'top' :
456
- pos . indexOf ( 'bottom' ) !== - 1 ? 'bottom' : 'middle' ,
457
- h = pos . indexOf ( 'left' ) !== - 1 ? 'end' :
458
- pos . indexOf ( 'right' ) !== - 1 ? 'start' : 'middle' ,
459
- fontSize = d . ts || trace . textfont . size ,
460
- // if markers are shown, offset a little more than
461
- // the nominal marker size
462
- // ie 2/1.6 * nominal, bcs some markers are a bit bigger
463
- r = d . mrc ? ( d . mrc / 0.8 + 1 ) : 0 ;
464
-
465
- fontSize = ( isNumeric ( fontSize ) && fontSize > 0 ) ? fontSize : 0 ;
572
+ var pos = d . tp || trace . textposition ;
573
+ var fontSize = extracTextFontSize ( d , trace ) ;
466
574
467
575
p . call ( drawing . font ,
468
576
d . tf || trace . textfont . family ,
469
577
fontSize ,
470
578
d . tc || trace . textfont . color )
471
- . attr ( 'text-anchor' , h )
472
579
. text ( text )
473
- . call ( svgTextUtils . convertToTspans , gd ) ;
580
+ . call ( svgTextUtils . convertToTspans , gd )
581
+ . call ( textPointPosition , pos , fontSize , d . mrc ) ;
582
+ } ) ;
583
+ } ;
474
584
475
- var pgroup = d3 . select ( this . parentNode ) ;
476
- var numLines = ( svgTextUtils . lineCount ( p ) - 1 ) * LINE_SPACING + 1 ;
477
- var dx = TEXTOFFSETSIGN [ h ] * r ;
478
- var dy = fontSize * 0.75 + TEXTOFFSETSIGN [ v ] * r +
479
- ( TEXTOFFSETSIGN [ v ] - 1 ) * numLines * fontSize / 2 ;
585
+ drawing . selectedTextStyle = function ( s , trace ) {
586
+ if ( ! s . size ( ) || ! trace . selectedpoints ) return ;
587
+
588
+ var selectedAttrs = trace . selected || { } ;
589
+ var unselectedAttrs = trace . unselected || { } ;
590
+
591
+ s . each ( function ( d ) {
592
+ var tx = d3 . select ( this ) ;
593
+ var tc = d . tc || trace . textfont . color ;
594
+ var tp = d . tp || trace . textposition ;
595
+ var fontSize = extracTextFontSize ( d , trace ) ;
596
+ var stc = ( selectedAttrs . textfont || { } ) . color ;
597
+ var utc = ( unselectedAttrs . textfont || { } ) . color ;
598
+ var tc2 ;
599
+
600
+ if ( d . selected ) {
601
+ if ( stc ) tc2 = stc ;
602
+ } else {
603
+ if ( utc ) tc2 = utc ;
604
+ else if ( ! stc ) tc2 = Color . addOpacity ( tc , DESELECTDIM ) ;
605
+ }
480
606
481
- // fix the overall text group position
482
- pgroup . attr ( 'transform' , 'translate(' + dx + ',' + dy + ')' ) ;
607
+ if ( tc2 ) Color . fill ( tx , tc2 ) ;
608
+ textPointPosition ( tx , tp , fontSize , d . mrc2 || d . mrc ) ;
483
609
} ) ;
484
610
} ;
485
611
0 commit comments