@@ -44,6 +44,9 @@ SpectrumChartD3 = function(elem, options) {
4444
4545 this . chart = typeof elem === 'string' ? document . getElementById ( elem ) : elem ;
4646
47+ // Apply no-select class to prevent text selection during chart interactions
48+ d3 . select ( this . chart ) . classed ( "spectrum-chart-no-select" , true ) ;
49+
4750 this . cx = this . chart . clientWidth ;
4851 this . cy = this . chart . clientHeight ;
4952
@@ -390,10 +393,10 @@ SpectrumChartD3 = function(elem, options) {
390393 ;
391394 /// @TODO triggering the cancel events on document.body and window is probably a bit agressive; could probably do this for just this.vis + on leave events
392395 d3 . select ( document . body )
393- . on ( "mouseup" , self . handleCancelAllMouseEvents ( ) )
396+ . on ( "mouseup.chart" + this . chart . id , self . handleCancelAllMouseEvents ( ) )
394397 d3 . select ( window )
395- . on ( "mouseup" , self . handleCancelAllMouseEvents ( ) )
396- . on ( "mousemove" , function ( ) {
398+ . on ( "mouseup.chart" + this . chart . id , self . handleCancelAllMouseEvents ( ) )
399+ . on ( "mousemove.chart" + this . chart . id , function ( ) {
397400 if ( d3 . event && ( self . sliderBoxDown || self . leftDragRegionDown || self . rightDragRegionDown || self . currentlyAdjustingSpectrumScale ) ) {
398401 //d3.event.preventDefault();
399402 //d3.event.stopPropagation();
@@ -560,8 +563,31 @@ SpectrumChartD3 = function(elem, options) {
560563 this . kineticRefLineCycleTimer = null ;
561564
562565 // Register global keyboard handler
563- d3 . select ( window ) . on ( "keydown" , this . keydown ( ) ) ;
564- }
566+ d3 . select ( window ) . on ( "keydown.chart" + this . chart . id , this . keydown ( ) ) ;
567+ }
568+
569+ /** Destructor method to properly clean up global event handlers. Call this before removing/destroying a chart. */
570+ SpectrumChartD3 . prototype . destroy = function ( ) {
571+ // Remove global event handlers using the namespaced IDs
572+ d3 . select ( window ) . on ( "keydown.chart" + this . chart . id , null ) ;
573+ d3 . select ( window ) . on ( "mouseup.chart" + this . chart . id , null ) ;
574+ d3 . select ( window ) . on ( "mousemove.chart" + this . chart . id , null ) ;
575+ d3 . select ( window ) . on ( "blur.chart" + this . chart . id , null ) ;
576+ d3 . select ( document . body ) . on ( "mouseup.chart" + this . chart . id , null ) ;
577+
578+ // Clear any active timers - we probably dont actually have to do this, probabilistically, but we will JIC
579+ window . clearTimeout ( this . mousewait ) ;
580+ window . clearTimeout ( this . touchHold ) ;
581+ window . clearTimeout ( this . wheeltimer ) ;
582+ window . clearTimeout ( this . roiDragRequestTimeout ) ;
583+ window . clearTimeout ( this . kineticRefLineCycleTimer ) ;
584+ window . cancelAnimationFrame ( this . zoomAnimationID ) ;
585+ this . mousewait = this . touchHold = this . wheeltimer = this . roiDragRequestTimeout = this . kineticRefLineCycleTimer = this . zoomAnimationID = null ;
586+
587+ d3 . select ( document . body ) . style ( "cursor" , "default" ) ; // Reset global cursor style
588+
589+ console . log ( "SpectrumChartD3 instance destroyed: " + this . chart . id ) ;
590+ } ;
565591
566592
567593
@@ -732,7 +758,6 @@ SpectrumChartD3.prototype.getStaticSvg = function(){
732758SpectrumChartD3 . prototype . dataPointDrag = function ( ) {
733759 var self = this ;
734760 return function ( d ) {
735- document . onselectstart = function ( ) { return false ; } ;
736761 self . selected = self . dragged = d ;
737762 self . update ( false ) ; /* boolean set to false to indicate no animation needed */
738763
@@ -3463,7 +3488,6 @@ SpectrumChartD3.prototype.mousemove = function () {
34633488SpectrumChartD3 . prototype . mouseup = function ( ) {
34643489 var self = this ;
34653490 return function ( ) {
3466- document . onselectstart = function ( ) { return true ; } ;
34673491 d3 . select ( 'body' ) . style ( "cursor" , "auto" ) ;
34683492 d3 . select ( 'body' ) . style ( "cursor" , "auto" ) ;
34693493 if ( self . xaxisdown ) {
@@ -5327,7 +5351,6 @@ SpectrumChartD3.prototype.yaxisDrag = function(d) {
53275351 var self = this ;
53285352 return function ( d ) {
53295353 console . log ( 'yaxisDrag work' ) ;
5330- document . onselectstart = function ( ) { return false ; } ;
53315354 var p = d3 . mouse ( self . vis [ 0 ] [ 0 ] ) ;
53325355 self . yaxisdown = self . yScale . invert ( p [ 1 ] ) ;
53335356 }
@@ -5618,7 +5641,6 @@ SpectrumChartD3.prototype.xaxisDrag = function() {
56185641 /*This function is called once when you click on an x-axis label (which you can then start dragging it) */
56195642 /* And NOT when you click on the chart and drag it to pan */
56205643
5621- document . onselectstart = function ( ) { return false ; } ;
56225644 var p = d3 . mouse ( self . vis [ 0 ] [ 0 ] ) ;
56235645
56245646 if ( self . xScale . invert ( p [ 0 ] ) > 0 ) { /* set self.xaxisdown equal to value of your mouse pos */
@@ -8270,7 +8292,7 @@ SpectrumChartD3.prototype.updateFeatureMarkers = function( mouseDownEnergy, over
82708292 /* If mouse edge could has been deleted, do not update the mouse edge */
82718293 if ( deleteMouseEdge ( ) )
82728294 return ;
8273-
8295+ console . log ( "updateMouseEdge" ) ;
82748296 /* Update the mouse edge and corresponding text position */
82758297 if ( self . mouseEdge ) {
82768298 self . mouseEdge
0 commit comments