@@ -40,7 +40,6 @@ Feature TODO list (created 20160220):
4040 - Move to using D3 v6 with modules to minimize code sizes and such.
4141 - For peak labels, make a border around text (maybe add some padding, maybe make border same color as peak), make background translucent so you can read the text even if in a cluttered area.
4242 - Make sure that d3 selections are iterated over using each(...), rather than forEach(...)
43- - lots of other issues
4443*/
4544
4645SpectrumChartD3 = function ( elem , options ) {
@@ -86,6 +85,7 @@ SpectrumChartD3 = function(elem, options) {
8685
8786 if ( ( typeof this . options . refLineWidth ) !== 'number' ) this . options . refLineWidth = 1 ;
8887 if ( ( typeof this . options . refLineWidthHover ) !== 'number' ) this . options . refLineWidthHover = 2 ;
88+ if ( ( typeof this . options . refLineVerbosity ) !== 'number' ) this . options . refLineVerbosity = 0 ;
8989 if ( ( typeof this . options . featureLineWidth ) !== 'number' ) this . options . featureLineWidth = 2 ;
9090
9191 this . options . refLineTopPad = 30 ;
@@ -401,6 +401,9 @@ SpectrumChartD3 = function(elem, options) {
401401 . on ( "touchstart" , self . handleChartTouchStart ( ) )
402402 . on ( "touchend" , self . handleChartTouchEnd ( ) )
403403 ;
404+
405+ // Handle window blur (alt-tab away) to clean up mouse interactions
406+ d3 . select ( window ) . on ( "blur.chart" + this . chart . id , self . handleChartMouseLeave ( ) ) ;
404407
405408 /*
406409 To allow markers to be updated while mouse is outside of the chart, but still inside the visual.
@@ -482,13 +485,6 @@ SpectrumChartD3 = function(elem, options) {
482485 . attr ( "x" , 0 )
483486 . attr ( "dy" , "1em" ) ;
484487
485- /*Add a small red circle on the x axis to help indicate which line the info is */
486- /* currently showing for. */
487- self . refLineInfo . append ( "circle" )
488- . attr ( "cx" , 0 )
489- . attr ( "cy" , self . size . height )
490- . attr ( "r" , 2 )
491- . style ( "fill" , "red" ) ;
492488
493489 this . chartBody = this . vis . append ( "g" )
494490 . attr ( "clip-path" , "url(#clip" + this . chart . id + ")" ) ;
@@ -1460,7 +1456,6 @@ SpectrumChartD3.prototype.handleResize = function( dontRedraw ) {
14601456
14611457 this . yAxisBody . attr ( "height" , this . size . height ) ;
14621458
1463- this . refLineInfo . select ( "circle" ) . attr ( "cy" , this . size . height ) ;
14641459 this . mouseInfo . attr ( "transform" , "translate(" + this . size . width + "," + this . size . height + ")" ) ;
14651460
14661461 if ( this . xGrid ) {
@@ -2243,6 +2238,15 @@ SpectrumChartD3.prototype.handleChartMouseLeave = function() {
22432238 self . mousedOverRefLine = null ;
22442239 self . refLineInfo . style ( "display" , "none" ) ;
22452240 self . mouseInfo . style ( "display" , "none" ) ;
2241+
2242+ const ref = self . vis . selectAll ( "g.ref" ) ;
2243+ ref . select ( "line.temp-extension" ) . remove ( ) ;
2244+ ref . select ( "circle.ref-hover-indicator" ) . remove ( ) ;
2245+ ref . selectAll ( "line" )
2246+ . attr ( "stroke-width" , self . options . refLineWidth ) ;
2247+ ref . select ( ".major-extension" )
2248+ . style ( "opacity" , 0.5 )
2249+ . style ( "stroke-width" , self . options . refLineWidth ) ;
22462250 }
22472251}
22482252
@@ -4057,13 +4061,13 @@ SpectrumChartD3.prototype.drawRefGammaLines = function() {
40574061 const h = self . size . height ;
40584062 const m = Math . min ( h , self . options . refLineTopPad ) ; // leave 20px margin at top of chart
40594063
4060- gy . enter ( ) . insert ( "g" , "a" )
4064+ gy . enter ( )
4065+ . insert ( "g" , "a" )
40614066 . attr ( "class" , "ref" )
40624067 . attr ( "transform" , tx )
40634068 . append ( "line" )
40644069 . style ( "stroke-dasharray" , dashfunc )
40654070 . attr ( "stroke" , stroke )
4066- . attr ( "stroke-width" , self . options . refLineWidth )
40674071 . attr ( "y1" , h )
40684072 . attr ( "dx" , "-0.5" ) ;
40694073
@@ -4086,9 +4090,34 @@ SpectrumChartD3.prototype.drawRefGammaLines = function() {
40864090 */
40874091
40884092 gy . select ( "line" )
4093+ . attr ( "stroke-width" , self . options . refLineWidth )
40894094 . attr ( "y2" , y2Lin )
40904095 //.attr("y2", y2Log )
40914096 . attr ( "y1" , h ) ; //needed for initial load sometimes
4097+
4098+ // Add dotted extension lines for major reference lines (only if refLineVerbosity >= 2)
4099+ if ( self . options . refLineVerbosity >= 2 ) {
4100+ const majorLines = gy . filter ( function ( d ) { return d . major ; } ) ;
4101+
4102+ // Remove any existing major line extensions
4103+ gy . select ( "line.major-extension" ) . remove ( ) ;
4104+
4105+ // Add dotted extension lines for major lines
4106+ const extension_dash = "" + self . options . refLineWidthHover + "," + 2 * self . options . refLineWidthHover ;
4107+ majorLines . append ( "line" )
4108+ . attr ( "class" , "major-extension" )
4109+ . style ( "stroke-dasharray" , extension_dash )
4110+ . style ( "opacity" , 0.5 )
4111+ . attr ( "stroke" , stroke )
4112+ . attr ( "stroke-width" , self . options . refLineWidth )
4113+ . attr ( "y1" , function ( d ) { return y2Lin ( d ) ; } )
4114+ . attr ( "y2" , self . options . refLineTopPad )
4115+ . attr ( "x1" , 0 )
4116+ . attr ( "x2" , 0 ) ;
4117+ } else {
4118+ // Remove any existing major line extensions if verbosity < 2
4119+ gy . select ( "line.major-extension" ) . remove ( ) ;
4120+ }
40924121}
40934122
40944123
@@ -4156,6 +4185,12 @@ SpectrumChartD3.prototype.setRefLineWidths = function( width, hoverWidth ) {
41564185 this . options . refLineWidth = width ;
41574186 this . options . refLineWidthHover = hoverWidth ;
41584187 this . drawRefGammaLines ( ) ;
4188+ this . updateMouseCoordText ( ) ;
4189+ }
4190+
4191+ SpectrumChartD3 . prototype . setRefLineVerbosity = function ( verbosity ) {
4192+ this . options . refLineVerbosity = verbosity ;
4193+ this . drawRefGammaLines ( ) ;
41594194}
41604195
41614196SpectrumChartD3 . prototype . setKineticReferenceLines = function ( data ) {
@@ -4412,7 +4447,26 @@ SpectrumChartD3.prototype.updateMouseCoordText = function() {
44124447 /* but with out it sometimes lines will stay fat that arent supposed to. */
44134448 /* Also, I think setting attr values is expensive, so only doing if necassary. */
44144449 if ( d . __data__ . mousedover && d !== self . mousedOverRefLine ) {
4415- d3 . select ( d ) . attr ( "stroke-width" , 1 ) . attr ( "dx" , "-0.5" ) ;
4450+ const dSelection = d3 . select ( d ) ;
4451+ dSelection
4452+ . attr ( "stroke-width" , self . options . refLineWidth )
4453+ . attr ( "dx" , - 0.5 * self . options . refLineWidth ) ;
4454+ // Handle extension line cleanup for this line
4455+ if ( self . options . refLineVerbosity >= 1 ) {
4456+ const dLinedata = d . __data__ ;
4457+
4458+ if ( dLinedata . major && self . options . refLineVerbosity >= 2 ) {
4459+ // For major lines with verbosity >= 2, reset the existing extension line
4460+ dSelection . select ( "line.major-extension" )
4461+ . attr ( "stroke-width" , self . options . refLineWidth )
4462+ . style ( "opacity" , 0.5 ) ;
4463+ } else {
4464+ // For non-major lines or major lines with verbosity == 1, remove the temporary extension line
4465+ dSelection . select ( "line.temp-extension" ) . remove ( ) ;
4466+ }
4467+ }
4468+ // Remove hover indicator circle
4469+ dSelection . select ( "circle.ref-hover-indicator" ) . remove ( ) ;
44164470 d . __data__ . mousedover = null ;
44174471 }
44184472
@@ -4426,7 +4480,27 @@ SpectrumChartD3.prototype.updateMouseCoordText = function() {
44264480
44274481 if ( nearestpx > 10 ) {
44284482 if ( self . mousedOverRefLine ) {
4429- d3 . select ( self . mousedOverRefLine ) . attr ( "stroke-width" , 1 ) . attr ( "dx" , "-0.5" ) ;
4483+ const prevLineSelection = d3 . select ( self . mousedOverRefLine ) ;
4484+ prevLineSelection
4485+ . select ( "line" )
4486+ . attr ( "dx" , - 0.5 * self . options . refLineWidth )
4487+ . attr ( "stroke-width" , self . options . refLineWidth ) ;
4488+ // Handle extension line cleanup for previously hovered line
4489+ if ( self . options . refLineVerbosity >= 1 ) {
4490+ const prevLinedata = self . mousedOverRefLine . __data__ ;
4491+
4492+ if ( prevLinedata . major && self . options . refLineVerbosity >= 2 ) {
4493+ // For major lines with verbosity >= 2, reset the existing extension line
4494+ prevLineSelection . select ( "line.major-extension" )
4495+ . attr ( "stroke-width" , self . options . refLineWidth )
4496+ . style ( "opacity" , 0.5 ) ;
4497+ } else {
4498+ // For non-major lines or major lines with verbosity == 1, remove the temporary extension line
4499+ prevLineSelection . select ( "line.temp-extension" ) . remove ( ) ;
4500+ }
4501+ }
4502+ // Remove hover indicator circle
4503+ prevLineSelection . select ( "circle.ref-hover-indicator" ) . remove ( ) ;
44304504 self . mousedOverRefLine . __data__ . mousedover = null ;
44314505 }
44324506 self . mousedOverRefLine = null ;
@@ -4438,7 +4512,27 @@ SpectrumChartD3.prototype.updateMouseCoordText = function() {
44384512 return ;
44394513
44404514 if ( self . mousedOverRefLine ) {
4441- d3 . select ( self . mousedOverRefLine ) . attr ( "stroke-width" , 1 ) . attr ( "dx" , "-0.5" ) ;
4515+ const prevLineSelection = d3 . select ( self . mousedOverRefLine ) ;
4516+ prevLineSelection
4517+ . select ( "line" )
4518+ . attr ( "dx" , - 0.5 * self . options . refLineWidth )
4519+ . attr ( "stroke-width" , self . options . refLineWidth ) ;
4520+ // Handle extension line cleanup for previously hovered line
4521+ if ( self . options . refLineVerbosity >= 1 ) {
4522+ const prevLinedata = self . mousedOverRefLine . __data__ ;
4523+
4524+ if ( prevLinedata . major && self . options . refLineVerbosity >= 2 ) {
4525+ // For major lines with verbosity >= 2, reset the existing extension line
4526+ prevLineSelection . select ( "line.major-extension" )
4527+ . attr ( "stroke-width" , self . options . refLineWidth )
4528+ . style ( "opacity" , 0.5 ) ;
4529+ } else {
4530+ // For non-major lines or major lines with verbosity == 1, remove the temporary extension line
4531+ prevLineSelection . select ( "line.temp-extension" ) . remove ( ) ;
4532+ }
4533+ }
4534+ // Remove hover indicator circle
4535+ prevLineSelection . select ( "circle.ref-hover-indicator" ) . remove ( ) ;
44424536 self . mousedOverRefLine . __data__ . mousedover = null ;
44434537 }
44444538
@@ -4478,6 +4572,11 @@ SpectrumChartD3.prototype.updateMouseCoordText = function() {
44784572 }
44794573
44804574 self . refLineInfo . style ( "display" , null ) . attr ( "transform" , "translate(" + linepx + ",0)" ) ;
4575+
4576+ // Add circle to the hovered reference line
4577+ const lineSelection = d3 . select ( nearestline ) ;
4578+ const nearLineEl = lineSelection . select ( "line" ) ;
4579+
44814580 var svgtxt = self . refLineInfoTxt . select ( "text" )
44824581 . attr ( "dy" , "1em" )
44834582 . attr ( "fill" , linedata . parent . color ) ;
@@ -4498,10 +4597,43 @@ SpectrumChartD3.prototype.updateMouseCoordText = function() {
44984597 self . refLineInfoTxt . attr ( "transform" , tx ) ;
44994598 }
45004599
4501- d3 . select ( nearestline )
4600+ nearLineEl
45024601 . attr ( "stroke-width" , self . options . refLineWidthHover )
4503- . select ( "line" )
4504- . attr ( "dx" , "-1" ) ;
4602+ . attr ( "dx" , - 0.5 * self . options . refLineWidthHover ) ;
4603+
4604+ // Handle extension line for hovered reference line (only if refLineVerbosity >= 1)
4605+ if ( self . options . refLineVerbosity >= 1 ) {
4606+ const hoveredLinedata = nearestline . __data__ ;
4607+ const nearestlineSelection = d3 . select ( nearestline ) ;
4608+
4609+ if ( hoveredLinedata . major && self . options . refLineVerbosity >= 2 ) {
4610+ // For major lines with verbosity >= 2, just modify the existing extension line
4611+ nearestlineSelection . select ( "line.major-extension" )
4612+ . attr ( "stroke-width" , self . options . refLineWidthHover )
4613+ . style ( "opacity" , 1.0 ) ;
4614+ } else {
4615+ // For non-major lines or major lines with verbosity == 1, add a temporary extension line
4616+ const y2Lin = function ( d ) { return Math . min ( h - ( h - m ) * d . h / d . parent . maxVisibleAmp , h - 2 ) ; } ;
4617+ nearestlineSelection . append ( "line" )
4618+ . attr ( "class" , "temp-extension" )
4619+ . style ( "stroke-dasharray" , "2,2" )
4620+ . attr ( "stroke" , hoveredLinedata . color ? hoveredLinedata . color : hoveredLinedata . parent . color )
4621+ . attr ( "stroke-width" , self . options . refLineWidthHover )
4622+ . attr ( "y1" , y2Lin ( hoveredLinedata ) )
4623+ . attr ( "y2" , self . options . refLineTopPad )
4624+ . attr ( "x1" , 0 )
4625+ . attr ( "x2" , 0 ) ;
4626+ }
4627+ }
4628+
4629+ lineSelection . select ( "circle.ref-hover-indicator" ) . remove ( ) ; // Remove any existing circle
4630+ const circleY = self . options . refLineVerbosity >= 1 ? nearLineEl . attr ( "y2" ) : self . size . height ;
4631+ lineSelection . append ( "circle" )
4632+ . attr ( "class" , "ref-hover-indicator" )
4633+ . attr ( "cx" , 0 )
4634+ . attr ( "cy" , circleY )
4635+ . attr ( "r" , 2 )
4636+ . style ( "fill" , "red" ) ;
45054637}
45064638
45074639SpectrumChartD3 . prototype . setShowMouseStats = function ( d ) {
0 commit comments