2f73d7595b0e37b159e9c9355f8e99512bf37e81 max Wed Sep 10 08:33:03 2025 -0700 Merging Jim Robinsons code into the kent tree. Due to whitespace changes in his IDE, I'm merging this manually. The original code is at https://github.com/igvteam/ucsc_dev/. changes up to 48816bc are included. Also adding an API call to get the 2bit file and code to use it. diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js index 5e07d09597f..887a8c2fd36 100644 --- src/hg/js/hgTracks.js +++ src/hg/js/hgTracks.js @@ -32,30 +32,34 @@ if (!String.prototype.startsWith) { String.prototype.startsWith = function(searchString, position) { position = position || 0; return this.indexOf(searchString, position) === position; }; } function initVars() { // There are various entry points, so we call initVars in several places to make sure all is well if (typeof(hgTracks) !== "undefined" && !genomePos.original) { // remember initial position and size so we can restore it if user cancels genomePos.original = genomePos.getOriginalPos(); genomePos.originalSize = $('#size').text().replace(/,/g, ""); // strip out any commas dragSelect.originalCursor = jQuery('body').css('cursor'); + if (typeof (igv) !== "undefined") { + igv.initIgvUcsc(); + } + imageV2.imgTbl = $('#imgTbl'); // imageV2.enabled === true unless: advancedJavascript===false, or trackSearch, or config pg imageV2.enabled = (imageV2.imgTbl && imageV2.imgTbl.length > 0); // jQuery load function with stuff to support drag selection in track img if (theClient.isSafari()) { // Safari has the following bug: if we update the hgTracks map dynamically, // the browser ignores the changes (even though if you look in the DOM the changes // are there). So we have to do a full form submission when the user changes // visibility settings or track configuration. // As of 5.0.4 (7533.20.27) this is problem still exists in safari. // As of 5.1 (7534.50) this problem appears to have been fixed - unfortunately, // logs for 7/2011 show vast majority of safari users are pre-5.1 (5.0.5 is by far // the most common). // @@ -1958,30 +1962,35 @@ if (newPortalEnd > hgTracks.chromEnd && bounded) { newPortalEnd = hgTracks.chromEnd; newPortalStart = newPortalEnd - portalWidthBases; recalculate = true; } if (newPortalStart > 0) { var newPos = hgTracks.chromName + ":" + newPortalStart + "-" + newPortalEnd; genomePos.set(newPos); // no need to change the size } if (recalculate && hgTracks.imgBoxBasesPerPixel > 0) { // Need to recalculate X for bounding drag portalScrolledX = (closedPortalStart - newPortalStart) / hgTracks.imgBoxBasesPerPixel; newOffsetX = portalScrolledX - (hgTracks.imgBoxPortalOffsetX+hgTracks.imgBoxLeftLabel); } + if (typeof (igv) !== "undefined") { + igv.updateIgvStartPosition(newPortalStart); + } + + ret = {}; ret.newX = newOffsetX; ret.isOutsideChrom = recalculate; return ret; } function mapTopAndBottom(mapName,east,west) { // Find the top and bottom px given left and right boundaries var mapPortal = { top: -10, bottom: -10 }; var items = $("map[name='"+mapName+"']").children(); if ($(items).length>0) { $(items).each(function(t) { var loc = this.coords.split(","); var aleft = parseInt(loc[0]); var aright = parseInt(loc[2]); @@ -4278,30 +4287,33 @@ } imageV2.loadRemoteTracks(); makeItemsByDrag.load(); imageV2.loadSuggestBox(); imageV2.drawHighlights(); if (imageV2.backSupport) { imageV2.setInHistory(false); // Set this new position into History stack } else { imageV2.markAsDirtyPage(); } if (typeof showMouseovers !== 'undefined' && showMouseovers) { convertTitleTagsToMouseovers(); } + if(typeof window.igvBrowser !== "undefined") { + window.igvBrowser.search(genomePos.get()); + } }, updateImgForId: function (html, id, fullImageReload, newJsonRec) { // update row in imgTbl for given id. // return true if we successfully pull slice for id and update it in imgTrack. var newTr = $(html).find("tr[id='tr_" + id + "']"); if (newTr.length > 0) { var tr = $(document.getElementById("tr_" + id)); if (tr.length > 0) { $(tr).html(newTr.children()); // Need to update tr class list too var classes = $(html).find("tr[id='tr_"+ id + "']")[0].className; if (classes && classes.length > 0) { $(tr).removeClass(); @@ -4478,30 +4490,31 @@ // force reload of whole page via trackform submit // This function does not return jQuery('body').css('cursor', 'wait'); if (extraData || cart.updatesWaiting()) { var url = cart.addUpdatesToUrl(window.location.href); if (extraData) { if ( url.lastIndexOf("?") === -1) url += "?" + extraData; else url += '&' + extraData; } window.location.assign(url); return false; } document.TrackHeaderForm.submit(); + window.igv.initUcsc(); }, updateImgAndMap: function (response, status) { // Handle ajax response with an updated trackMap image, map and optional ideogram. // and maybe the redLines background too. // this.cmd can be used to figure out which menu item triggered this. // this.id === appropriate track if we are retrieving just a single track. // update local hgTracks.trackDb to reflect possible side-effects of ajax request. var newJson = scrapeVariable(response, "hgTracks"); //alert(JSON.stringify(newJson)); // DEBUG Example var oldJson = hgTracks; @@ -6022,15 +6035,55 @@ var skipNotification = localStorage.getItem("hgTracks.hideSpeedNotification"); dumpCart(loadSeconds, skipNotification); if (skipNotification) return; msg = "This page took "+loadSeconds+" seconds to load, more than "+maxSeconds+" seconds. We strive to keep "+ "the UCSC Genome Browser quick and responsive. See our "+ "display speed FAQ for "+ "common causes and solutions to slow performance. If this problem continues, you can create a "+ "session link via My Data > My Sessions and send the link to genome-www@soe.ucsc.edu."; notifBoxSetup("hgTracks", "hideSpeedNotification", msg); notifBoxShow("hgTracks", "hideSpeedNotification"); } + +////////////////////////// +// Attempt to support panning by dragging IGV track. The dragging works, but its not clear to do on drag end. + +document.addEventListener('DOMContentLoaded', function () { + if (typeof igv !== 'undefined') { + + // TODO -- probably should use genomePos.get() and set() here, but I (JTR) don't fully understand that + // object and calling set() seems to have side effects. So this variable is a placeholder. + + const pos = {}; + + igv.ucscTrackpan = (newPosition) => { + + const positionOffset = (newPosition - hgTracks.imgBoxPortalStart); + const pixelOffset = Math.round(positionOffset / hgTracks.imgBoxBasesPerPixel); + const newX = -(pixelOffset + hgTracks.imgBoxLeftLabel); + var nowPos = newX.toString() + "px"; + $(".panImg").css({'left': nowPos}); + $('.tdData').css({'backgroundPosition': nowPos}); + + pos.chrom = hgTracks.chromName; + pos.start = Math.round(newPosition + 1); + pos.end = pos.start + (hgTracks.winEnd - hgTracks.winStart); // Dragging will not change the bp width + + $('#positionDisplay').text(pos.chrom + ":" + commify(pos.start) + "-" + commify(pos.end)); + }; + + igv.ucscTrackpanEnd = () => { + if (imageV2.inPlaceUpdate) { + imageV2.navigateInPlace("db=" + getDb() + "&position=" + + encodeURIComponent(pos.chrom + ":" + pos.start + "-" + pos.end), + null, false); + } else { + document.TrackHeaderForm.submit(); + } + }; + } +}); +