5fef9ecfe121867dc6bd750a6a01b46150bb868e
hiram
  Tue Nov 3 15:46:21 2020 -0800
dirty checkin for transition to click through to description page working and streamline the popUp text window definition refs #21980

diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index 9f76930..6da3b50 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -4460,192 +4460,221 @@
 };
 
   ///////////////////////////////////////
  //// mouseOver data display 2020-10 ///
 ///////////////////////////////////////
 var mouseOver = {
 
     spans: {},
     visible: false,
     tracks: {},
     popUpDelay: 1000,   // one second delay before popUp appears
     popUpTimer: null,// handle from setTimeout to use in clearTimout(popUpTimer)
     delayDone: true,   // mouse has not left element, still receiving move evts
     delayInProgress: false,        // true if working with delay timer done
     mostRecentMouseEvt: null,
+    mouseMoveCount: 0,
+    mouseDelayCount: 0,
+    mouseInTrackCount: 0,
 
     // spans{} - key name is track name, value is an array of
     //                   objects: {x1, x2, value}
     // visible - keep track of window visible or not, value: true|false
     //           shouldn't need to do this here, the window knows if it
     //           is visible or not, just ask it for status
     // tracks{}  - tracks that were set up initially, key is track name
     //             value is the number of boxes (for debugging)
 
     // given hgt_....png file name, change to trackName_....json file name
     jsonFileName: function(imgElement, trackName)
     {
       var jsonFile=imgElement.src.replace("hgt/hgt_", "hgt/" + trackName + "_");
       jsonFile = jsonFile.replace(".png", ".json");
       return jsonFile;
     },
 
     // called from: updateImgForId when it has updated a track in place
     // need to refresh the event handlers and json data
     updateMouseOver: function (trackName)
     {
       if (mouseOver.tracks[trackName]) {
       // there should be a more simple jQuery function to bind these events
       var tdData = "td_data_" + trackName;
-      var tdElement  = document.getElementById(tdData);
-      var id = tdElement.id;
-      tdElement.addEventListener('mousemove', mouseOver.mouseMoveDelay);
-      tdElement.addEventListener('mouseout', mouseOver.popUpDisappear);
+      var tdDataId  = document.getElementById(tdData);
+      $( tdDataId ).mousemove(mouseOver.mouseMoveDelay);
+      $( tdDataId ).mouseout(mouseOver.popUpDisappear);
+//      $( tdDataId ).bind('mousemove', mouseOver.mouseMoveDelay);
+//      $( tdDataId ).bind('mouseout', mouseOver.popUpDisappear);
+//      tdDataId.addEventListener('mousemove', mouseOver.mouseMoveDelay, true);
+//      tdDataId.addEventListener('mouseout', mouseOver.popUpDisappear, true);
       var imgData = "img_data_" + trackName;
       var imgElement  = document.getElementById(imgData);
       mouseOver.fetchMapData(mouseOver.jsonFileName(imgElement, trackName), trackName);
       }
     },
 
     // given an X coordinate: x, find the index idx
     // in the rects[idx] array where rects[idx].x1 <= x < rects[idx].x2
     // returning -1 when not found
     // if we knew the array was sorted on x1 we could get out early
     //   when x < x1
     findRange: function (x, rects)
     {
       var answer = -1;  // assmume not found
       for ( var idx in rects ) {
          if ((rects[idx].x1 <= x) && (x < rects[idx].x2)) {
            answer = idx;
            break;
          }
       }
       return answer;
     },
 
     popUpDisappear: function () {
       if (mouseOver.visible) {        // should *NOT* have to keep track !*!
 //       $('#mouseOverText').hide();       // does not function ?
-        var msgWindow = document.querySelector(".wigMouseOver");
-        msgWindow.classList.toggle("showMouseOver");
+//        var msgWindow = document.querySelector(".wigMouseOver");
+//        msgWindow.classList.toggle("showMouseOver");
         mouseOver.visible = false;
+//   hPrintf("<div id='mouseOverText' class='mouseOverText'></div>\n");
 //        $('#mouseOverContainer').css('display','none'); // does not work
-        $('#mouseOverLine').css('display','none');
+        $('#mouseOverText').css('display','none');
+        $('#mouseOverVerticalLine').css('display','none');
       }
       if (mouseOver.popUpTimer) {
          clearTimeout(mouseOver.popUpTimer);
          mouseOver.popUpTimer = null;
       }
       mouseOver.delayDone = true;
       mouseOver.delayInProgress = false;
     },
 
     popUpVisible: function () {
       if (! mouseOver.visible) {        // should *NOT* have to keep track !*!
 //      $('#mouseOverText').show();     // does not function ?
-      var msgWindow = document.querySelector(".wigMouseOver");
-        msgWindow.classList.toggle("showMouseOver");
+//      var msgWindow = document.querySelector(".wigMouseOver");
+//        msgWindow.classList.toggle("showMouseOver");
         mouseOver.visible = true;
 //        $('#mouseOverContainer').css('display','block');  // does not work
-        $('#mouseOverLine').css('display','block');
+        $('#mouseOverText').css('display','block');
+        $('#mouseOverVerticalLine').css('display','block');
       }
     },
+//   hPrintf("<div id='mouseOverVerticalLine' class='mouseOverVerticalLine'></div>\n");
+//   hPrintf("<div id='mouseOverText' class='mouseOverText'></div>\n");
 
-    //the evt.target.id is the img_data_<trackName> element of the track graphic
+    //the evt.currentTarget.id is the td_data_<trackName> element of the track graphic
     mouseInTrackImage: function (evt)
     {
+    ++mouseOver.mouseInTrackCount;
+
+//      var msg = ". . . mouseInTrackImage: evt.currentTarget.id: " + evt.currentTarget.id + ", mouseMoveCount: " + mouseOver.mouseMoveCount + ", mouseDelayCount: " + mouseOver.mouseDelayCount + ", mouseInTrackCount: " + mouseOver.mouseInTrackCount;
+//      $('#debugMsg').html(msg);
+
     // the center label also events here, can't use that
     //  plus there is a one pixel line under the center label that has no
     //   id name at all, so verify we are getting the event from the correct
     //   element.
-    if (! evt.target.id.includes("img_data_")) { return; }
-    var trackName = evt.target.id.replace("img_data_", "");
+    if (! evt.currentTarget.id.includes("td_data_")) { return; }
+    var trackName = evt.currentTarget.id.replace("td_data_", "");
     if (trackName.length < 1) { return; }	// verify valid trackName
     // find location of this <td> slice in the image, this is the track
     //   image in the graphic, including left margin and center label
     //   This location follows the window scrolling, could go negative
-    var tdName = "td_data_" + trackName;
-    var tdId  = document.getElementById(tdName);
+//    var tdName = "td_data_" + trackName;
+    var tdId  = document.getElementById(evt.currentTarget.id);
     var tdRect = tdId.getBoundingClientRect();
     var tdLeft = Math.floor(tdRect.left);
     var tdTop = Math.floor(tdRect.top);
     var tdHeight = Math.floor(tdRect.height);
     // find the location of the image itself, this could be the single complete
     //  graphic image of all the tracks, or possibly the single image of the
     //  track itself.  This location also follows the window scrolling and can
     //  even go negative when the web browser scrolls a window that is larger
     //  than the width of the web browser.
-    var imageId = document.getElementById(evt.target.id);
+    var imageName = "img_data_" + trackName;
+    var imageId = document.getElementById(imageName);
     var imageRect = imageId.getBoundingClientRect();
     var imageLeft = Math.floor(imageRect.left);
     var imageTop = Math.floor(imageRect.top);
 //    var imageHeight = Math.floor(imageRect.height);
-    var srcUrl = evt.target.src;
-    var evX = evt.x;      // location of mouse on the web browser screen
-    var evY = evt.y;
-    var offLeft = Math.max(0, Math.floor(evt.x - tdLeft));
+    var evtX = evt.pageX;      // location of mouse on the web browser screen
+    var evtY = evt.pageY;
+    var offLeft = Math.max(0, Math.floor(evtX - tdLeft));
     var windowUp = false;     // see if window is supposed to become visible
     var foundIdx = -1;
     if (mouseOver.spans[trackName]) {
        foundIdx = mouseOver.findRange(offLeft, mouseOver.spans[trackName]);
     }
+// var msg = ". . . tdRect: " + tdLeft + "," + tdTop + ", imgRect: " + imageLeft + "," + imageTop + ", evtXY: " + evtX + "," + evtY + ", offLeft: " + offLeft + ", foundIdx: " + foundIdx;
+//      $('#debugMsg').html(msg);
     // might want to indicate 'no data' when not found
     if (foundIdx > -1) {
       // value to display
       var mouseOverValue = "&nbsp;" + mouseOver.spans[trackName][foundIdx].v + "&nbsp;";
       $('#mouseOverText').html(mouseOverValue);
       var msgWidth = Math.ceil($('#mouseOverText').width());
       var msgHeight = Math.ceil($('#mouseOverText').height());
-      var posLeft = evt.x - msgWidth + "px";
+      var posLeft = evtX - msgWidth + "px";
       var posTop = tdTop + "px";
-      $('#mouseOverContainer').css('left',posLeft);
-      $('#mouseOverContainer').css('top',posTop);
-      $('#mouseOverLine').css('left',evt.x + "px");
-      $('#mouseOverLine').css('top',posTop);
+// var msg = ". . . posLeft,Top: " + posLeft + "," + posTop + ", evXY: " + evtX + "," + evtY + ", imageTop: " + imageTop;
+//      $('#debugMsg').html(msg);
+      $('#mouseOverText').css('left',posLeft);
+      $('#mouseOverText').css('top',posTop);
+      $('#mouseOverVerticalLine').css('left',evtX + "px");
+      $('#mouseOverVerticalLine').css('top',posTop);
+//      msg = ". . . mouseOverText: " + mouseOverValue + " at: " + posLeft + "," + posTop;
+//      $('#debugMsg').html(msg);
       // Setting the height of this line to the full image height eliminates
       //  the mouse event area
-      $('#mouseOverLine').css('height',tdHeight + "px");
-//      $('#mouseOverLine').height(imageHeight + "px");
+      $('#mouseOverVerticalLine').css('height',tdHeight + "px");
+//      $('#mouseOverVerticalLine').height(imageHeight + "px");
       windowUp = true;      // yes, window is to become visible
     }
     if (windowUp) {     // the window should become visible
       mouseOver.popUpVisible();
     } else {    // the window should disappear
       mouseOver.popUpDisappear();
     } //      window visible/not visible
     },  //      mouseInTrackImage function (evt)
 
     // timeout calls here upon completion
     delayCompleted: function()
     {
+       ++mouseOver.mouseDelayCount;
        mouseOver.delayDone = true;
        // mouse could just be sitting there with no events, if there
        // have been events during the timer, the evt has been recorded
        // so the popUp appears where the mouse is while it moved during the
        // time delay since mostRecentMouseEvt is up to date to now
        // If mouse has moved out of element during timeout, the
        // delayInProgress will be false and nothing happens.
        if (mouseOver.delayInProgress) {
           mouseOver.mouseInTrackImage(mouseOver.mostRecentMouseEvt);
        }
     },
 
     // all mouse move events come here even during timeout
     mouseMoveDelay: function (evt)
     {
+      ++mouseOver.mouseMoveCount;
+
       mouseOver.mostRecentMouseEvt = evt;   // record evt for delayCompleted
+
+//      var msg = ". . . mouseMoveDelay evt.currentTarget.id: " + evt.currentTarget.id + ", mouseMoveCount: " + mouseOver.mouseMoveCount + ", mouseDelayCount: " + mouseOver.mouseDelayCount + ", mouseInTrackCount: " + mouseOver.mouseInTrackCount;
+//      $('#debugMsg').html(msg);
+
       if (mouseOver.delayInProgress) {
         if (mouseOver.delayDone) {
           mouseOver.mouseInTrackImage(evt);	// OK to trigger event now
           return;
         } else {
           return; // wait for delay to be done
         }
       }
       mouseOver.delayDone = false;
       mouseOver.delayInProgress = true;
       if (mouseOver.popUpTimer) {
          clearTimeout(mouseOver.popUpTimer);
          mouseOver.popUpTimer = null;
       }
       mouseOver.popUpTimer = setTimeout(mouseOver.delayCompleted, mouseOver.popUpDelay);
@@ -4665,33 +4694,42 @@
     //        where n is an integer in the range: 0..width,
     //        and s is the value string to display
     //     Will need to get them sorted on x1 for efficient searching as
     //     they accumulate in the local data structure here.
     // =======================================================================
     receiveData: function (arr)
     {
       mouseOver.visible = false;
       for (var trackName in arr) {
       mouseOver.spans[trackName] = [];      // start array
       // add a 'mousemove' and 'mouseout' event listener to each track
       //     display object
       var tdData = "td_data_" + trackName;
       var tdDataId  = document.getElementById(tdData);
       if (! tdDataId) { return; } // not sure why objects are not always found
+// from jQuery doc:
+//  As the .mousemove() method is just a shorthand
+//    for .on( "mousemove", handler ), detaching is possible
+//      using .off( "mousemove" ).
       // there should be a more simple jQuery function to bind these events
-      tdDataId.addEventListener('mousemove', mouseOver.mouseMoveDelay);
-      tdDataId.addEventListener('mouseout', mouseOver.popUpDisappear);
+//      $(tdData).bind('mousemove', mouseOver.mouseMoveDelay); does not work
+      $( tdDataId ).mousemove(mouseOver.mouseMoveDelay);
+      $( tdDataId ).mouseout(mouseOver.popUpDisappear);
+//      $( tdDataId ).bind('mousemove', mouseOver.mouseMoveDelay);
+//      $( tdDataId ).bind('mouseout', mouseOver.popUpDisappear);
+//      tdDataId.addEventListener('mousemove', mouseOver.mouseMoveDelay, true);
+//      tdDataId.addEventListener('mouseout', mouseOver.popUpDisappear, true);
       var itemCount = 0;	// just for monitoring purposes
       // save incoming x1,x2,v data into the mouseOver.spans[trackName][] array
       for (var span in arr[trackName]) {
         mouseOver.spans[trackName].push(arr[trackName][span]);
        ++itemCount;
       }
       mouseOver.tracks[trackName] = itemCount;	// merely for debugging watch
       }
     },  //      receiveData: function (arr)
 
     failedRequest: function(trackName)
     {   // failed request to get json data, remove it from the track list
       if (mouseOver.tracks[trackName]) {
 //      alert("failed request trackName: '"+ trackName + "'");
         delete mouseOver.tracks[trackName];