c2e376e7b6d980f41ff903e6374378d668f11770
kate
Thu Oct 22 14:41:52 2020 -0700
Multi-region features for sparse tracks. With virt->multi, needs debug. refs #26385
diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js
index 0635e06..a023cd3 100644
--- src/hg/js/hgTracks.js
+++ src/hg/js/hgTracks.js
@@ -176,31 +176,31 @@
// overlap with position?
// if intersection,
if (w.winEnd > start && end > w.winStart) {
var s = Math.max(start, w.winStart);
var e = Math.min(end, w.winEnd);
var cs = s - w.winStart + w.virtStart;
var ce = e - w.winStart + w.virtStart;
if (newStart === -1)
newStart = cs;
newEnd = ce;
}
lastW = w;
}
}
// return new virt undisguised position as a string
- var newPos = "virt:" + (newStart+1) + "-" + newEnd;
+ var newPos = "multi:" + (newStart+1) + "-" + newEnd;
return newPos;
},
disguiseSize: function(position) // DISGUISE VMODE
{ // find the real size of the windows spanned
// position should be a real chrom span
var pos = parsePosition(position);
if (!pos)
return 0;
var start = pos.start - 1;
var end = pos.end;
var newSize = 0;
var windows = null;
for (j=0; j < 3; ++j) {
if (j === 0) windows = hgTracks.windowsBefore;
@@ -268,59 +268,60 @@
},
set: function (position, size)
{ // Set value of position and size (in hiddens and input elements).
// We assume size has already been commified.
// Either position or size may be null.
// stack dump // DEBUG
//console.trace();
// NOT work on safari
//var obj = {};
//Error.captureStackTrace(obj);
//warn("genomePos.set() called "+obj.stack);
position = position.replace(/,/g, ""); // strip out any commas
+ position.replace("virt:", "multi:");
if (position) {
// DISGUISE VMODE
//warn("genomePos.set() called, position = "+position);
- if (hgTracks.virtualSingleChrom && (position.search("virt:")===0)) {
+ if (hgTracks.virtualSingleChrom && (position.search("multi:")===0)) {
var newPosition = genomePos.disguisePosition(position);
//warn("genomePos.set() position = "+position+", newPosition = "+newPosition);
position = newPosition;
}
}
if (position) {
// There are multiple tags with name === "position"
// (one in TrackHeaderForm and another in TrackForm).
var tags = document.getElementsByName("position");
for (var i = 0; i < tags.length; i++) {
var ele = tags[i];
ele.value = position;
}
}
var pos = parsePosition(position);
if ($('#positionDisplay').length) {
// add commas to positionDisplay
var commaPosition = position;
if (pos)
commaPosition = pos.chrom+":"+commify(pos.start)+"-"+commify(pos.end);
$('#positionDisplay').text(commaPosition);
}
if (size) {
- if (hgTracks.virtualSingleChrom && (position.search("virt:")!==0)) {
+ if (hgTracks.virtualSingleChrom && (position.search("multi:")!==0)) {
var newSize = genomePos.disguiseSize(position);
//warn("genomePos.set() position = "+position+", newSize = "+newSize);
if (newSize > 0)
size = newSize;
}
$('#size').text(commify(size)); // add commas
}
if (pos) {
// fixup external static links on page'
// Example ensembl link:
// http://www.ensembl.org/Homo_sapiens/contigview?chr=21&start=33031934&end=33041241
genomePos.linkFixup(pos, "ensemblLink", new RegExp("(.+start=)[0-9]+"), "end");
// Example NCBI Map Viewer link (obsolete):
@@ -544,43 +545,44 @@
url: "../cgi-bin/hgTracks",
data: cart.varsToUrlData({ 'hgt.convertChromToVirtChrom': pos, 'hgt.trackImgOnly' : 1, 'hgsid': getHgsid() }),
dataType: "html",
trueSuccess: genomePos.handleConvertChromPosToVirtCoords,
success: catchErrorOrDispatch,
error: errorHandler,
cache: false
});
return genomePos.convertedVirtCoords;
},
positionDisplayDialog: function ()
// Show the virtual and real positions of the windows
{
var position = genomePos.get();
+ position.replace("virt:", "multi:");
var positionDialog = $("#positionDialog")[0];
if (!positionDialog) {
$("body").append("
");
positionDialog = $("#positionDialog")[0];
}
if (hgTracks.windows) {
var i, len, end;
- var matches = /^virt:[0-9]+-([0-9]+)/.exec(position);
+ var matches = /^multi:[0-9]+-([0-9]+)/.exec(position);
var str = position;
if (matches) {
end = matches[1];
if (end < hgTracks.chromEnd) {
- str += " (full virtual region is virt:1-" + hgTracks.chromEnd + ")";
+ str += " (full virtual region is multi:1-" + hgTracks.chromEnd + ")";
}
}
if (!(hgTracks.virtualSingleChrom && (hgTracks.windows.length === 1))) {
str += " \n";
str += " \n";
str += "
\n";
for (i=0,len=hgTracks.windows.length; i < len; ++i) {
var w = hgTracks.windows[i];
str += "
\n";
}
$("#positionDisplayPosition").html(str);
} else {
@@ -1040,30 +1042,31 @@
continue; // ignore invalid position strings
pos.start--;
if (pos.chrom === hgTracks.chromName && pos.db === currDb
&& pos.start <= findPos.chromStart && pos.end >= findPos.chromEnd) {
return i;
}
}
}
return null;
},
highlightThisRegion: function(newPosition, doAdd, hlColor)
// set highlighting newPosition in server-side cart and apply the highlighting in local UI.
{
+ newPosition.replace("virt:", "multi:");
var hlColorName = hlColor; // js convention: do not assign to argument variables
if (hlColor==="" || hlColor===null || hlColor===undefined)
hlColorName = dragSelect.hlColor;
var pos = parsePosition(newPosition);
var start = pos.start;
var end = pos.end;
var newHighlight = makeHighlightString(getDb(), pos.chrom, start, end, hlColorName);
newHighlight = imageV2.disguiseHighlight(newHighlight);
var oldHighlight = hgTracks.highlight;
if (oldHighlight===undefined || doAdd===undefined || doAdd===false || oldHighlight==="") {
// just set/overwrite the old highlight position, this used to be the default
hgTracks.highlight = newHighlight;
}
else {
@@ -1100,30 +1103,31 @@
}
}
if (nonVirtChrom !== "")
cartSettings.nonVirtHighlight = makeHighlightString(getDb(), nonVirtChrom, nonVirtStart, (nonVirtEnd+1), hlColorName);
} else if (hgTracks.windows && hgTracks.virtualSingleChrom) {
cartSettings.nonVirtHighlight = hgTracks.highlight;
}
// TODO if not virt, do we need to erase cart nonVirtHighlight ?
cart.setVarsObj(cartSettings);
imageV2.highlightRegion();
},
selectionEndDialog: function (newPosition)
// Let user choose between zoom-in and highlighting.
{
+ newPosition.replace("virt:", "multi:");
// if the user hit Escape just before, do not show this dialo
if (dragSelect.startTime===null)
return;
var dragSelectDialog = $("#dragSelectDialog")[0];
if (!dragSelectDialog) {
$("body").append("
" +
"
"+
"
Hold Shift+drag to show this dialog" +
"
Hold Alt+drag to add a highlight" +
"
Hold Ctrl+drag (Windows) or Cmd+drag (Mac) to zoom" +
"
To cancel, press Esc anytime or drag mouse outside image" +
"
Highlight the current position with h then m" +
"
Clear all highlights with View - Clear Highlights or h then c" +
"
" +
"
Highlight color: " +
@@ -1155,31 +1159,31 @@
showPalette: true,
showInput: true,
preferredFormat: "hex",
change: function() { var color = $("#hlColorPicker").spectrum("get"); $('#hlColorInput').val(color); },
};
$("#hlColorPicker").spectrum(opt);
// update the color picker if you change the input box
$("#hlColorInput").change(function(){ $("#hlColorPicker").spectrum("set", $('#hlColorInput').val()); });
}
$("#hlColorPicker").spectrum("set", $('#hlColorInput').val());
if (hgTracks.windows) {
var i,len;
var newerPosition = newPosition;
- if (hgTracks.virtualSingleChrom && (newPosition.search("virt:")===0)) {
+ if (hgTracks.virtualSingleChrom && (newPosition.search("multi:")===0)) {
newerPosition = genomePos.disguisePosition(newPosition);
}
var str = newerPosition + " \n";
var str2 = " \n";
str2 += "
\n";
var pos = parsePosition(newPosition);
var start = pos.start - 1;
var end = pos.end;
var selectedRegions = 0;
for (i=0,len=hgTracks.windows.length; i < len; ++i) {
var w = hgTracks.windows[i];
// overlap with new position?
if (w.virtEnd > start && end > w.virtStart) {
var s = Math.max(start, w.virtStart);
var e = Math.min(end, w.virtEnd);
@@ -1200,31 +1204,31 @@
$(dragSelectDialog).dialog({
modal: true,
title: "Drag-and-select",
closeOnEscape: true,
resizable: false,
autoOpen: false,
revertToOriginalPos: true,
minWidth: 500,
buttons: {
"Zoom In": function() {
// Zoom to selection
$(this).dialog("option", "revertToOriginalPos", false);
if ($("#disableDragHighlight").attr('checked'))
hgTracks.enableHighlightingDialog = false;
if (imageV2.inPlaceUpdate) {
- if (hgTracks.virtualSingleChrom && (newPosition.search("virt:")===0)) {
+ if (hgTracks.virtualSingleChrom && (newPosition.search("multi:")===0)) {
newPosition = genomePos.disguisePosition(newPosition); // DISGUISE
}
var params = "position=" + newPosition;
if (!hgTracks.enableHighlightingDialog)
params += "&enableHighlightingDialog=0";
imageV2.navigateInPlace(params, null, true);
} else {
$('body').css('cursor', 'wait');
if (!hgTracks.enableHighlightingDialog)
cart.setVarsObj({'enableHighlightingDialog': 0 },null,false); // async=false
document.TrackHeaderForm.submit();
}
$(this).dialog("close");
},
"Single Highlight": function() {
@@ -1289,44 +1293,45 @@
return false;
// ignore releases outside of the image rectangle (allowing a 10 pixel slop)
if (genomePos.check(img, selection)) {
// ignore single clicks that aren't in the top of the image
// (this happens b/c the clickClipHeight test in dragSelect.selectStart
// doesn't occur when the user single clicks).
doIt = (dragSelect.startTime !== null || rulerClicked);
}
if (doIt) {
// dragSelect.startTime is null if mouse has never been moved
var singleClick = ( (selection.x2 === selection.x1)
|| dragSelect.startTime === null
|| (now.getTime() - dragSelect.startTime) < 100);
var newPosition = genomePos.update(img, selection, singleClick);
+ newPosition.replace("virt:", "multi:");
if (newPosition) {
if (event.altKey) {
// with the alt-key, only highlight the region, do not zoom
dragSelect.highlightThisRegion(newPosition, true);
$(imageV2.imgTbl).imgAreaSelect({hide:true});
} else {
if (hgTracks.enableHighlightingDialog && !(event.metaKey || event.ctrlKey))
// don't show the dialog if: clicked on ruler, if dialog deactivated or meta/ctrl was pressed
dragSelect.selectionEndDialog(newPosition);
else {
// in every other case, show the dialog
$(imageV2.imgTbl).imgAreaSelect({hide:true});
if (imageV2.inPlaceUpdate) {
- if (hgTracks.virtualSingleChrom && (newPosition.search("virt:")===0)) {
+ if (hgTracks.virtualSingleChrom && (newPosition.search("multi:")===0)) {
newPosition = genomePos.disguisePosition(newPosition); // DISGUISE
}
imageV2.navigateInPlace("position=" + newPosition, null, true);
} else {
jQuery('body').css('cursor', 'wait');
document.TrackHeaderForm.submit();
}
}
}
} else {
$(imageV2.imgTbl).imgAreaSelect({hide:true});
genomePos.revertToOriginalPos();
}
dragSelect.startTime = null;
// blockMapClicks/allowMapClicks() is necessary if selectEnd was over a map item.
@@ -3334,35 +3339,36 @@
} else if (hgTracks.windows && hgTracks.nonVirtPosition) {
position = hgTracks.nonVirtPosition;
}
var pos = parsePosition(position);
if (pos) {
var url = "hgc?hgsid="+getHgsid()+"&g=getDna&i=mixed&c="+pos.chrom+"&l="+pos.start+"&r="+pos.end+"&db="+getDb();
window.location.href = url;
}
return false;
}
// A function for the keyboard shortcuts "zoom to x bp"
function zoomTo(zoomSize) {
var flankSize = Math.floor(zoomSize/2);
var pos = parsePosition(genomePos.get());
+ pos.replace("virt:", "multi:");
var mid = pos.start+(Math.floor((pos.end-pos.start)/2));
var newStart = Math.max(mid - flankSize, 0);
var newEnd = mid + flankSize - 1;
var newPos = genomePos.setByCoordinates(pos.chrom, newStart, newEnd);
- if (hgTracks.virtualSingleChrom && (newPos.search("virt:")===0))
+ if (hgTracks.virtualSingleChrom && (newPos.search("multi:")===0))
newPos = genomePos.disguisePosition(newPosition); // DISGUISE?
imageV2.navigateInPlace("position="+newPos, null, true);
}
// A function for the keyboard shortcuts "highlight add/clear/new"
function highlightCurrentPosition(mode) {
var pos = genomePos.get();
if (mode=="new")
dragSelect.highlightThisRegion(pos, false);
else if (mode=="add")
dragSelect.highlightThisRegion(pos, true);
else {
hgTracks.highlight = "";
var cartSettings = {'highlight': ""};
cart.setVarsObj(cartSettings);