1f4bdbe42a9a575812cd8de8419ed7a951a24e1c
hiram
  Fri Nov 6 16:41:56 2020 -0800
centered the message text and might now recognize when tracks turn on when they were silent refs #21980

diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index 0436c2a..8e473c1 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -4481,39 +4481,57 @@
     // 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]) {
       var tdData = "td_data_" + trackName;
       var tdDataId  = document.getElementById(tdData);
-        $( tdDataId ).mousemove(mouseOver.mouseMoveDelay);
-        $( tdDataId ).mouseout(mouseOver.popUpDisappear);
       var imgData = "img_data_" + trackName;
       var imgElement  = document.getElementById(imgData);
+      if (mouseOver.tracks[trackName]) {
+        if (tdDataId) {
+          $( tdDataId ).mousemove(mouseOver.mouseMoveDelay);
+          $( tdDataId ).mouseout(mouseOver.popUpDisappear);
+          if (imgElement) {
+            mouseOver.fetchMapData(mouseOver.jsonFileName(imgElement, trackName), trackName);
+          }
+        }
+      } else {
+        var trackType = hgTracks.trackDb[trackName].type;
+        var validType = false;
+        if (trackType.indexOf("wig") === 0) { validType = true; }
+        if (trackType.indexOf("bigWig") === 0) { validType = true; }
+        if (validType) {
+          if (tdDataId) {
+            $( tdDataId ).mousemove(mouseOver.mouseMoveDelay);
+            $( tdDataId ).mouseout(mouseOver.popUpDisappear);
+            if (imgElement) {
               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;
          }
@@ -4557,57 +4575,59 @@
 
     // location of mouse relative to the whole page
     //     even when the top of page has scolled off
     var evtX = Math.floor(evt.pageX);
 //  var evtY = Math.floor(evt.pageY);
 //  var offX = Math.floor(evt.offsetX);       // no need for evtY or offX
 
     // 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 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);
+    // clientX appears to be the X coordinate of the mouse hot spot
     var clientX = Math.floor(evt.clientX);
     // the graphOffset is the index (x coordinate) into the 'spans' definitions
     //  of the data value boxes for the graph.  The magic number three
     //   is used elsewhere in this code, note the comment on the constant
     //   LEFTADD.
     var graphOffset = Math.max(0, clientX - tdLeft - 3);
 
     var windowUp = false;     // see if window is supposed to become visible
     var foundIdx = -1;
     if (mouseOver.spans[trackName]) {
        foundIdx = mouseOver.findRange(graphOffset, mouseOver.spans[trackName]);
     }
     // can show 'no data' when not found
     var mouseOverValue = "no data";
     if (foundIdx > -1) { // value to display
       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 = clientX - msgWidth + "px";
-    var posTop = tdTop + "px";
-    $('#mouseOverText').css('left',posLeft);
-    $('#mouseOverText').css('top',posTop);
+    var lineHeight = Math.max(0, tdHeight - msgHeight);
+    var lineTop = Math.max(0, tdTop + msgHeight);
+    var msgLeft = Math.max(0, clientX - (msgWidth/2));
+    $('#mouseOverText').css('left',msgLeft + "px");
+    $('#mouseOverText').css('top',tdTop + "px");
     $('#mouseOverVerticalLine').css('left',clientX + "px");
-    $('#mouseOverVerticalLine').css('top',posTop);
-    $('#mouseOverVerticalLine').css('height',tdHeight + "px");
+    $('#mouseOverVerticalLine').css('top',lineTop + "px");
+    $('#mouseOverVerticalLine').css('height',lineHeight + "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.delayDone = true;
        // mouse could just be sitting there with no events, if there
        // have been events during the timer, the evt has been recorded
@@ -4706,34 +4726,36 @@
              mouseOver.failedRequest(trackName);
           }
        }
     };
     xmlhttp.open("GET", url, true);
     xmlhttp.send();  // sends request and exits this function
                      // the onreadystatechange callback above will trigger
                      // when the data has safely arrived
     },
 
     getData: function ()
     {
       // check for the hidden div elements for mouseOverData
       var trackList = document.getElementsByClassName("mouseOverData");
       for (var i = 0; i < trackList.length; i++) {
-        var jsonData = trackList[i].getAttribute('jsonData');
         var trackName = trackList[i].getAttribute('name');
+        var jsonData = trackList[i].getAttribute('jsonData');
+        if (jsonData) {
           mouseOver.fetchMapData(jsonData, trackName);
         }
+      }
     },
 
     // any scrolling turns the popUp message off
     scroll: function()
     {
     if (mouseOver.visible) { mouseOver.popUpDisappear(); }
     },
 
     addListener: function () {
         mouseOver.visible = false;
         window.addEventListener('scroll', mouseOver.scroll, false);
         window.addEventListener('load', mouseOver.getData, false);
     }
 };	//	var mouseOver