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();
+ }
+ };
+ }
+});
+