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 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 = " " + mouseOver.spans[trackName][foundIdx].v + " "; } $('#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