@@ -22,6 +22,7 @@ var svgTextUtils = require('../../lib/svg_text_utils');
2222var xmlnsNamespaces = require ( '../../constants/xmlns_namespaces' ) ;
2323var alignment = require ( '../../constants/alignment' ) ;
2424var LINE_SPACING = alignment . LINE_SPACING ;
25+ var DESELECTDIM = require ( '../../constants/interactions' ) . DESELECTDIM ;
2526
2627var subTypes = require ( '../../traces/scatter/subtypes' ) ;
2728var makeBubbleSizeFn = require ( '../../traces/scatter/make_bubble_size_func' ) ;
@@ -247,18 +248,22 @@ drawing.symbolNumber = function(v) {
247248 return Math . floor ( Math . max ( v , 0 ) ) ;
248249} ;
249250
251+ function makePointPath ( symbolNumber , r ) {
252+ var base = symbolNumber % 100 ;
253+ return drawing . symbolFuncs [ base ] ( r ) + ( symbolNumber >= 200 ? DOTPATH : '' ) ;
254+ }
255+
250256function singlePointStyle ( d , sel , trace , markerScale , lineScale , marker , markerLine , gd ) {
251- // only scatter & box plots get marker path and opacity
252- // bars, histograms don't
253257 if ( Registry . traceIs ( trace , 'symbols' ) ) {
254258 var sizeFn = makeBubbleSizeFn ( trace ) ;
255259
256260 sel . attr ( 'd' , function ( d ) {
257261 var r ;
258262
259263 // 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 {
262267 r = subTypes . isBubble ( trace ) ?
263268 sizeFn ( d . ms ) : ( marker . size || 6 ) / 2 ;
264269 }
@@ -267,21 +272,20 @@ function singlePointStyle(d, sel, trace, markerScale, lineScale, marker, markerL
267272 d . mrc = r ;
268273
269274 // 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 ;
272276
273277 // save if this marker is open
274278 // because that impacts how to handle colors
275279 d . om = x % 200 >= 100 ;
276280
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 ) ;
282282 } ) ;
283283 }
284284
285+ sel . style ( 'opacity' , function ( d ) {
286+ return ( d . mo + 1 || marker . opacity + 1 ) - 1 ;
287+ } ) ;
288+
285289 var perPointGradient = false ;
286290
287291 // 'so' is suspected outliers, for box plots
@@ -409,7 +413,6 @@ drawing.singlePointStyle = function(d, sel, trace, markerScale, lineScale, gd) {
409413 var marker = trace . marker ;
410414
411415 singlePointStyle ( d , sel , trace , markerScale , lineScale , marker , marker . line , gd ) ;
412-
413416} ;
414417
415418drawing . pointStyle = function ( s , trace , gd ) {
@@ -426,6 +429,84 @@ drawing.pointStyle = function(s, trace, gd) {
426429 } ) ;
427430} ;
428431
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+
429510drawing . tryColorscale = function ( marker , prefix ) {
430511 var cont = prefix ? Lib . nestedProperty ( marker , prefix ) . get ( ) : marker ,
431512 scl = cont . colorscale ,
@@ -439,8 +520,39 @@ drawing.tryColorscale = function(marker, prefix) {
439520 else return Lib . identity ;
440521} ;
441522
442- // draw text at points
443523var 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
444556drawing . textPointStyle = function ( s , trace , gd ) {
445557 s . each ( function ( d ) {
446558 var p = d3 . select ( this ) ;
@@ -451,35 +563,43 @@ drawing.textPointStyle = function(s, trace, gd) {
451563 return ;
452564 }
453565
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 ) ;
466568
467569 p . call ( drawing . font ,
468570 d . tf || trace . textfont . family ,
469571 fontSize ,
470572 d . tc || trace . textfont . color )
471- . attr ( 'text-anchor' , h )
472573 . text ( text )
473- . call ( svgTextUtils . convertToTspans , gd ) ;
574+ . call ( svgTextUtils . convertToTspans , gd )
575+ . call ( textPointPosition , pos , fontSize , d . mrc ) ;
576+ } ) ;
577+ } ;
474578
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+ }
480600
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 ) ;
483603 } ) ;
484604} ;
485605
0 commit comments