c3e7b398ffd33e71d9810e6f8906e3caf57290a3 hiram Mon Oct 26 15:54:45 2020 -0700 correctly following window scrolling refs #21980 diff --git src/hg/js/mouseOver.js src/hg/js/mouseOver.js index 0db0224..cca9571 100644 --- src/hg/js/mouseOver.js +++ src/hg/js/mouseOver.js @@ -34,62 +34,59 @@ } } return answer; } function mouseLeftTrackImage(evt) { if (mapData.visible) { var mouseOver = document.querySelector(".wigMouseOver"); mouseOver.classList.toggle("showMouseOver"); mapData.visible = false; } } function mouseInTrackImage(evt) { var trackName = evt.target.id.replace("img_data_", ""); - var firstRect = ""; - if (mapData.spans[trackName]) { - var lastRect = mapData.spans[trackName].length - 1; - firstRect = mapData.spans[trackName][lastRect].x1 + ".." + mapData.spans[trackName][lastRect].x2; - } var evX = evt.x; var evY = evt.y; - var oLeft = $(this).offset().left; - var oTop = $(this).offset().top; var offLeft = Math.max(0, Math.floor(evt.x - $(this).offset().left)); var windowUp = false; // see if window is supposed to become visible var foundIdx = -1; var valP = "noX"; if (mapData.spans[trackName]) { foundIdx = findRange(offLeft, mapData.spans[trackName]); } if (foundIdx > -1) { + var tdName = "td_data_" + trackName; + var elId = document.getElementById(tdName); + var rectBounds = elId.getBoundingClientRect(); + var rectTop = Math.floor(rectBounds.top); // follows window scrolling + var rectLeft = Math.floor(rectBounds.left); valP = mapData.spans[trackName][foundIdx].v; // value to display var msg = " " + mapData.spans[trackName][foundIdx].v + " "; $('#mouseOverText').html(msg); var msgWidth = Math.ceil($('#mouseOverText').width()); var msgHeight = Math.ceil($('#mouseOverText').height()); - var posLeft = (evt.x - msgWidth) + "px"; -// var posTop = (oTop + rect.y1) + "px"; - var posTop = oTop + "px"; + var posLeft = offLeft + (rectLeft - msgWidth) + "px"; + var posTop = rectTop + "px"; $('#mouseOverContainer').css('left',posLeft); $('#mouseOverContainer').css('top',posTop); windowUp = true; // yes, window is to become visible } var offTop = Math.max(0, Math.floor(evt.y - $(this).offset().top)); - var msg = "<p>. . . mouse in target.id: " + evt.target.id + "(" + trackName + ")[" + foundIdx + "]='" + valP + "' [" + firstRect + "] at " + offLeft + "," + offTop + ", evX,Y: " + evX + "," + evY + ", offL,T: " + oLeft + "," + oTop + "</p>"; + var msg = "<p>. . . mouse in target.id: " + evt.target.id + "(" + trackName + ")[" + foundIdx + "]='" + valP + "' at " + offLeft + "," + offTop + ", evX,Y: " + evX + "," + evY + "</p>"; $('#eventRects').html(msg); if (windowUp) { // the window should become visible if (! mapData.visible) { // should *NOT* have to keep track !*! var contain = document.getElementById('mouseOverContainer'); var mouseOver = document.querySelector(".wigMouseOver"); mouseOver.classList.toggle("showMouseOver"); mapData.visible = true; } } else { // the window should disappear if (mapData.visible) { var mouseOver = document.querySelector(".wigMouseOver"); mouseOver.classList.toggle("showMouseOver"); mapData.visible = false; } } // window visible/not visible @@ -109,55 +106,56 @@ // 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. // ========================================================================= function receiveData(arr) { if (typeof mapData.spans === 'undefined') { mapData.spans = {}; // get this object started first time mapData.tracks = []; mapData.boxCount = []; } mapData.visible = false; for (var trackName in arr) { mapData.tracks.push(trackName); mapData.spans[trackName] = []; // start array - // add a 'mousemove' event listener to each track display object + // add a 'mousemove' and 'mouseout' event listener to each track + // display object var objectName = "td_data_" + trackName; var objectId = document.getElementById(objectName); objectId.addEventListener('mousemove', mouseInTrackImage); objectId.addEventListener('mouseout', mouseLeftTrackImage); var itemCount = 0; // just for monitoring purposes // save incoming x1,x2,v data into the mapData.spans[trackName][] array arr[trackName].forEach(function(box) { mapData.spans[trackName].push(box); ++itemCount}); mapData.boxCount.push(itemCount); // merely for debugging watch } - var msg = "<ul>"; - for (var idx in mapData.tracks) { - var trackName = mapData.tracks[idx]; - var imgData = "td_data_" + trackName; - var imgMap = document.getElementById(imgData); - var imageRect = imgMap.getBoundingClientRect(); - var top = Math.floor(imageRect.top); - var left = Math.floor(imageRect.left); - var width = Math.floor(imageRect.width); - var height = Math.floor(imageRect.height); - msg += "<li>" + trackName + " at left,top (x,y)(w,h):" + left + "," + top + "(" + width + "," + height + ") has: " + mapData.boxCount[idx] + " mapBoxes</li>"; - } - msg += "</ul>"; - $('#debugMsg').html(msg); +// var msg = "<ul>"; +// for (var idx in mapData.tracks) { +// var trackName = mapData.tracks[idx]; +// var imgData = "td_data_" + trackName; +// var imgMap = document.getElementById(imgData); +// var imageRect = imgMap.getBoundingClientRect(); +// var top = Math.floor(imageRect.top); +// var left = Math.floor(imageRect.left); +// var width = Math.floor(imageRect.width); +// var height = Math.floor(imageRect.height); +// msg += "<li>" + trackName + " at left,top (x,y)(w,h):" + left + "," + top + "(" + width + "," + height + ") has: " + mapData.boxCount[idx] + " mapBoxes</li>"; +// } +// msg += "</ul>"; +// $('#debugMsg').html(msg); } // ========================================================================= // fetchMapData() sends JSON request, callback to receiveData() upon return // ========================================================================= function fetchMapData(url) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (4 === this.readyState && 200 === this.status) { var mapData = JSON.parse(this.responseText); receiveData(mapData); } }; xmlhttp.open("GET", url, true); xmlhttp.send(); // sends request and exits this function