1bad77cde561abffb1db68d686ddd1de11ef8649 hiram Fri Oct 30 21:27:35 2020 -0700 correctly handle failedRequest and smaller vertical line however once a track is knocked out it does not come back with zoom in refs #21980 diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js index 2e634c7..92e8630 100644 --- src/hg/js/hgTracks.js +++ src/hg/js/hgTracks.js @@ -4455,30 +4455,31 @@ imageV2.history.pushState({lastDbPos: newDbPos, position: newPos, hgsid: + sid },title, "hgTracks?db="+getDb()+"&"+newDbPos+"&hgsid="+sid); } } } }; /////////////////////////////////////// //// mouseOver data display 2020-10 /// /////////////////////////////////////// var mouseOver = { spans: {}, visible: false, tracks: {}, +// popUpDelay: 100000, // can not get this to work ? // 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; @@ -4515,106 +4516,123 @@ 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"); mouseOver.visible = false; // $('#mouseOverContainer').css('display','none'); // does not work $('#mouseOverLine').css('display','none'); } +// mouseOver.popUpDelay = 100000; }, 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"); mouseOver.visible = true; // $('#mouseOverContainer').css('display','block'); // does not work $('#mouseOverLine').css('display','block'); } +// mouseOver.popUpDelay = 10; }, //the evt.target.id is the img_data_<trackName> element of the track graphic mouseInTrackImage: function (evt) { // 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 (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 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 imageRect = imageId.getBoundingClientRect(); var imageLeft = Math.floor(imageRect.left); var imageTop = Math.floor(imageRect.top); - var imageHeight = Math.floor(imageRect.height); +// 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 windowUp = false; // see if window is supposed to become visible var foundIdx = -1; if (mouseOver.spans[trackName]) { foundIdx = mouseOver.findRange(offLeft, mouseOver.spans[trackName]); } // might want to indicate 'no data' when not found if (foundIdx > -1) { // value to display var mouseOverValue = " " + mouseOver.spans[trackName][foundIdx].v + " "; $('#mouseOverText').html(mouseOverValue); var msgWidth = Math.ceil($('#mouseOverText').width()); var msgHeight = Math.ceil($('#mouseOverText').height()); var posLeft = evt.x - msgWidth + "px"; var posTop = tdTop + "px"; $('#mouseOverContainer').css('left',posLeft); $('#mouseOverContainer').css('top',posTop); $('#mouseOverLine').css('left',evt.x + "px"); $('#mouseOverLine').css('top',posTop); // Setting the height of this line to the full image height eliminates // the mouse event area -// $('#mouseOverLine').css('height',imageHeight + "px"); + $('#mouseOverLine').css('height',tdHeight + "px"); // $('#mouseOverLine').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) +/* this doesn't work, claims there is an error in security policy + mouseMoveDelay: function (evt) + { + if (mouseOver.popUpDelay == 100000) { // first time here + mouseOver.popUpDelay -= 1; // no longer first time + setTimeout(mouseOver.mouseInTrackImage(evt), mouseOver.popUpDelay); + } else if (mouseOver.popUpDelay > 10) { + return; // wait for first one to complete before issuing more + } else { + mouseOver.mouseInTrackImage(evt); // after first one is done, pass them along + } + }, +*/ + // ======================================================================= // receiveData() callback for successful JSON request, receives incoming // JSON data and gets it into global variables for use here. // The incoming 'arr' is a a set of objects where the object key name is // the track name, used here as an array reference: arr[trackName] // (currently only one object per json file, one file for each track, // this may change to have multiple tracks in one json file.) // The value associated with each track name // is an array of span definitions, where each element in the array is a // mapBox definition object: // {x1:n, x2:n, value:s} // 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. @@ -4650,31 +4668,31 @@ } }, // ========================================================================= // fetchMapData() sends JSON request, callback to receiveData() upon return // ========================================================================= fetchMapData: function (url, trackName) { var xmlhttp = new XMLHttpRequest(); xmlhttp.onreadystatechange = function() { if (4 === this.readyState && 200 === this.status) { var mapData = JSON.parse(this.responseText); mouseOver.receiveData(mapData); } else { if (4 === this.readyState && 404 === this.status) { - failedRequest(trackName); + 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 () { // verify hgTracks and hgTracks.trackDb exist before running wild if (typeof(hgTracks) !== "undefined") { if (typeof (hgTracks.trackDb) !== "undefined") { for (var trackName in hgTracks.trackDb) { var rec = hgTracks.trackDb[trackName];