@@ -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' ) ;
@@ -247,18 +248,22 @@ drawing.symbolNumber = function(v) {
247
248
return Math . floor ( Math . max ( v , 0 ) ) ;
248
249
} ;
249
250
251
+ function makePointPath ( symbolNumber , r ) {
252
+ var base = symbolNumber % 100 ;
253
+ return drawing . symbolFuncs [ base ] ( r ) + ( symbolNumber >= 200 ? DOTPATH : '' ) ;
254
+ }
255
+
250
256
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
257
if ( Registry . traceIs ( trace , 'symbols' ) ) {
254
258
var sizeFn = makeBubbleSizeFn ( trace ) ;
255
259
256
260
sel . attr ( 'd' , function ( d ) {
257
261
var r ;
258
262
259
263
// handle multi-trace graph edit case
260
- if ( d . ms === 'various' || marker . size === 'various' ) r = 3 ;
261
- else {
264
+ if ( d . ms === 'various' || marker . size === 'various' ) {
265
+ r = 3 ;
266
+ } else {
262
267
r = subTypes . isBubble ( trace ) ?
263
268
sizeFn ( d . ms ) : ( marker . size || 6 ) / 2 ;
264
269
}
@@ -267,21 +272,20 @@ function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerL
267
272
d . mrc = r ;
268
273
269
274
// turn the symbol into a sanitized number
270
- var x = drawing . symbolNumber ( d . mx || marker . symbol ) || 0 ,
271
- xBase = x % 100 ;
275
+ var x = drawing . symbolNumber ( d . mx || marker . symbol ) || 0 ;
272
276
273
277
// save if this marker is open
274
278
// because that impacts how to handle colors
275
279
d . om = x % 200 >= 100 ;
276
280
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 ;
281
+ return makePointPath ( x , r ) ;
282
282
} ) ;
283
283
}
284
284
285
+ sel . style ( 'opacity' , function ( d ) {
286
+ return ( d . mo + 1 || marker . opacity + 1 ) - 1 ;
287
+ } ) ;
288
+
285
289
var perPointGradient = false ;
286
290
287
291
// 'so' is suspected outliers, for box plots
@@ -409,7 +413,6 @@ drawing.singlePointStyle = function(d, sel, trace, markerScale, lineScale, gd) {
409
413
var marker = trace . marker ;
410
414
411
415
singlePointStyle ( d , sel , trace , markerScale , lineScale , marker , marker . line , gd ) ;
412
-
413
416
} ;
414
417
415
418
drawing . pointStyle = function ( s , trace , gd ) {
@@ -426,6 +429,84 @@ drawing.pointStyle = function(s, trace, gd) {
426
429
} ) ;
427
430
} ;
428
431
432
+ drawing . selectedPointStyle = function ( s , trace ) {
433
+ if ( ! s . size ( ) || ! trace . selectedpoints ) return ;
434
+
435
+ var selectedAttrs = trace . selected || { } ;
436
+ var unselectedAttrs = trace . unselected || { } ;
437
+
438
+ var marker = trace . marker || { } ;
439
+ var selectedMarker = selectedAttrs . marker || { } ;
440
+ var unselectedMarker = unselectedAttrs . marker || { } ;
441
+
442
+ var mo = marker . opacity ;
443
+ var smo = selectedMarker . opacity ;
444
+ var usmo = unselectedMarker . opacity ;
445
+ var smoIsDefined = smo !== undefined ;
446
+ var usmoIsDefined = usmo !== undefined ;
447
+
448
+ s . each ( function ( d ) {
449
+ var pt = d3 . select ( this ) ;
450
+ var dmo = d . mo ;
451
+ var dmoIsDefined = dmo !== undefined ;
452
+ var mo2 ;
453
+
454
+ if ( dmoIsDefined || smoIsDefined || usmoIsDefined ) {
455
+ if ( d . selected ) {
456
+ if ( smoIsDefined ) mo2 = smo ;
457
+ } else {
458
+ if ( usmoIsDefined ) mo2 = usmo ;
459
+ else mo2 = DESELECTDIM * ( dmoIsDefined ? dmo : mo ) ;
460
+ }
461
+ }
462
+
463
+ if ( mo2 !== undefined ) pt . style ( 'opacity' , mo2 ) ;
464
+ } ) ;
465
+
466
+ var smc = selectedMarker . color ;
467
+ var usmc = unselectedMarker . color ;
468
+
469
+ if ( smc || usmc ) {
470
+ s . each ( function ( d ) {
471
+ var pt = d3 . select ( this ) ;
472
+ var mc2 ;
473
+
474
+ if ( d . selected ) {
475
+ if ( smc ) mc2 = smc ;
476
+ } else {
477
+ if ( usmc ) mc2 = usmc ;
478
+ }
479
+
480
+ if ( mc2 ) Color . fill ( pt , mc2 ) ;
481
+ } ) ;
482
+ }
483
+
484
+ var sms = selectedMarker . size ;
485
+ var usms = unselectedMarker . size ;
486
+ var smsIsDefined = sms !== undefined ;
487
+ var usmsIsDefined = usms !== undefined ;
488
+
489
+ if ( Registry . traceIs ( trace , 'symbols' ) && ( smsIsDefined || usmsIsDefined ) ) {
490
+ s . each ( function ( d ) {
491
+ var pt = d3 . select ( this ) ;
492
+ var mrc = d . mrc ;
493
+ var mx = d . mx || marker . symbol || 0 ;
494
+ var mrc2 ;
495
+
496
+ if ( d . selected ) {
497
+ mrc2 = ( smsIsDefined ) ? sms / 2 : mrc ;
498
+ } else {
499
+ mrc2 = ( usmsIsDefined ) ? usms / 2 : mrc ;
500
+ }
501
+
502
+ pt . attr ( 'd' , makePointPath ( drawing . symbolNumber ( mx ) , mrc2 ) ) ;
503
+
504
+ // save for selectedTextStyle
505
+ d . mrc2 = mrc2 ;
506
+ } ) ;
507
+ }
508
+ } ;
509
+
429
510
drawing . tryColorscale = function ( marker , prefix ) {
430
511
var cont = prefix ? Lib . nestedProperty ( marker , prefix ) . get ( ) : marker ,
431
512
scl = cont . colorscale ,
@@ -439,8 +520,39 @@ drawing.tryColorscale = function(marker, prefix) {
439
520
else return Lib . identity ;
440
521
} ;
441
522
442
- // draw text at points
443
523
var TEXTOFFSETSIGN = { start : 1 , end : - 1 , middle : 0 , bottom : 1 , top : - 1 } ;
524
+
525
+ function textPointPosition ( s , textPosition , fontSize , markerRadius ) {
526
+ var group = d3 . select ( s . node ( ) . parentNode ) ;
527
+
528
+ var v = textPosition . indexOf ( 'top' ) !== - 1 ?
529
+ 'top' :
530
+ textPosition . indexOf ( 'bottom' ) !== - 1 ? 'bottom' : 'middle' ;
531
+ var h = textPosition . indexOf ( 'left' ) !== - 1 ?
532
+ 'end' :
533
+ textPosition . indexOf ( 'right' ) !== - 1 ? 'start' : 'middle' ;
534
+
535
+ // if markers are shown, offset a little more than
536
+ // the nominal marker size
537
+ // ie 2/1.6 * nominal, bcs some markers are a bit bigger
538
+ var r = markerRadius ? markerRadius / 0.8 + 1 : 0 ;
539
+
540
+ var numLines = ( svgTextUtils . lineCount ( s ) - 1 ) * LINE_SPACING + 1 ;
541
+ var dx = TEXTOFFSETSIGN [ h ] * r ;
542
+ var dy = fontSize * 0.75 + TEXTOFFSETSIGN [ v ] * r +
543
+ ( TEXTOFFSETSIGN [ v ] - 1 ) * numLines * fontSize / 2 ;
544
+
545
+ // fix the overall text group position
546
+ s . attr ( 'text-anchor' , h ) ;
547
+ group . attr ( 'transform' , 'translate(' + dx + ',' + dy + ')' ) ;
548
+ }
549
+
550
+ function extracTextFontSize ( d , trace ) {
551
+ var fontSize = d . ts || trace . textfont . size ;
552
+ return ( isNumeric ( fontSize ) && fontSize > 0 ) ? fontSize : 0 ;
553
+ }
554
+
555
+ // draw text at points
444
556
drawing . textPointStyle = function ( s , trace , gd ) {
445
557
s . each ( function ( d ) {
446
558
var p = d3 . select ( this ) ;
@@ -451,35 +563,43 @@ drawing.textPointStyle = function(s, trace, gd) {
451
563
return ;
452
564
}
453
565
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 ;
566
+ var pos = d . tp || trace . textposition ;
567
+ var fontSize = extracTextFontSize ( d , trace ) ;
466
568
467
569
p . call ( drawing . font ,
468
570
d . tf || trace . textfont . family ,
469
571
fontSize ,
470
572
d . tc || trace . textfont . color )
471
- . attr ( 'text-anchor' , h )
472
573
. text ( text )
473
- . call ( svgTextUtils . convertToTspans , gd ) ;
574
+ . call ( svgTextUtils . convertToTspans , gd )
575
+ . call ( textPointPosition , pos , fontSize , d . mrc ) ;
576
+ } ) ;
577
+ } ;
474
578
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 ;
579
+ drawing . selectedTextStyle = function ( s , trace ) {
580
+ if ( ! s . size ( ) || ! trace . selectedpoints ) return ;
581
+
582
+ var selectedAttrs = trace . selected || { } ;
583
+ var unselectedAttrs = trace . unselected || { } ;
584
+
585
+ s . each ( function ( d ) {
586
+ var tx = d3 . select ( this ) ;
587
+ var tc = d . tc || trace . textfont . color ;
588
+ var tp = d . tp || trace . textposition ;
589
+ var fontSize = extracTextFontSize ( d , trace ) ;
590
+ var stc = ( selectedAttrs . textfont || { } ) . color ;
591
+ var utc = ( unselectedAttrs . textfont || { } ) . color ;
592
+ var tc2 ;
593
+
594
+ if ( d . selected ) {
595
+ if ( stc ) tc2 = stc ;
596
+ } else {
597
+ if ( utc ) tc2 = utc ;
598
+ else if ( ! stc ) tc2 = Color . addOpacity ( tc , DESELECTDIM ) ;
599
+ }
480
600
481
- // fix the overall text group position
482
- pgroup . attr ( 'transform' , 'translate(' + dx + ',' + dy + ')' ) ;
601
+ if ( tc2 ) Color . fill ( tx , tc2 ) ;
602
+ textPointPosition ( tx , tp , fontSize , d . mrc2 || d . mrc ) ;
483
603
} ) ;
484
604
} ;
485
605
0 commit comments