fecc0bfffd30dccc9998aa0c2e5a6064d487bbb1 chmalee Fri Apr 10 15:39:54 2020 -0700 Initial work on merging multiple bigBed items that span the window, refs #25133 diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js index 7fb1abe..3494f3a 100644 --- src/hg/js/hgTracks.js +++ src/hg/js/hgTracks.js @@ -714,30 +714,43 @@ // Verify that click-competing operation (e.g. dragging) isn't currently occurring. { return (posting.blockUseMap === false); }, blockTheMapOnMouseMove: function (ev) { if (!posting.blockUseMap && mouse.hasMoved(ev)) { posting.blockUseMap=true; } }, mapClk: function () { var done = false; + // if we clicked on a merged item then show all the items, similar to clicking a + // dense track to turn it to pack + if (this && this.href && this.href.indexOf("i=mergedItem") !== -1) { + var id = this.href.slice(this.href.indexOf("&g=")); + id = id.split(/&[^=]+=/)[1]; + updateObj={}; + updateObj[id+".doMergeItems"] = 0; + hgTracks.trackDb[id][id+".doMergeItems"] = 0; + cart.setVarsObj(updateObj,null,false); + imageV2.requestImgUpdate(id, id + ".doMergeItems=0"); + return false; + } + if (false && imageV2.inPlaceUpdate) { // XXXX experimental and only turned on in larrym's tree. // Use in-place update if the map item just modifies the current position (this is nice // because it's faster and preserves the users relative position in the track image). // // First test handles next/prev item. var str = "/cgi-bin/hgTracks\\?position=([^:]+):(.+)&hgsid=(\\d+)" + "&(hgt.(next|prev)Item=[^&]+)"; var reg = new RegExp(str); var a = reg.exec(this.href); if (a && a[1] && a[1] === hgTracks.chromName) { imageV2.navigateInPlace("position=" + encodeURIComponent(a[1] + ":" + a[2]) + "&" + a[4], null, true); done = true; } else { @@ -2899,31 +2912,46 @@ } else { genomePos.setByCoordinates(newPos.chrom, newPos.start, newPos.end); jQuery('body').css('cursor', 'wait'); document.TrackHeaderForm.submit(); } } } } else if (cmd === 'removeHighlight') { var highlights = hgTracks.highlight.split("|"); highlights.splice(rightClick.clickedHighlightIdx, 1); // splice = remove element from array hgTracks.highlight = highlights.join("|"); cart.setVarsObj({'highlight' : hgTracks.highlight}); imageV2.highlightRegion(); - + } else if (cmd === 'toggleMerge') { + // toggle both the cart (if the user goes to trackUi) + // and toggle args[key], if the user doesn't leave hgTracks + var key = id + ".doMergeItems"; + var updateObj = {}; + if (args[key] === 1) { + args[key] = 0; + updateObj[key] = 0; + cart.setVarsObj(updateObj,null,false); + imageV2.requestImgUpdate(id, id + ".doMergeItems=0"); + } else { + args[key] = 1; + updateObj[key] = 1; + cart.setVars(updateObj,null,false); + imageV2.requestImgUpdate(id, id + ".doMergeItems=1"); + } } else { // if ( cmd in 'hide','dense','squish','pack','full','show' ) // Change visibility settings: // // First change the select on our form: rec = hgTracks.trackDb[id]; selectUpdated = vis.update(id, cmd); // Now change the track image if (imageV2.enabled && cmd === 'hide') { // Hide local display of this track and update server side cart. // Subtracks controlled by 2 settings so del vis and set sel=0. if (tdbIsSubtrack(rec)) { // Remove subtrack level vis and explicitly uncheck. cart.setVars( [ id, id+"_sel" ], [ '[]', 0 ] ); } else if (tdbIsFolderContent(rec)) { @@ -3088,31 +3116,31 @@ } } done = true; } } } if (done) { o = {}; var any = false; var title = rightClick.selectedMenuItem.title || "feature"; var maxLength = 60; if (title.length > maxLength) { title = title.substring(0, maxLength) + "..."; } - if (isGene || isHgc || id === "wikiTrack") { + if ((isGene || isHgc || id === "wikiTrack") && href.indexOf("i=mergedItem") === -1) { // Add "Open details..." item var displayItemFunctions = false; if (rec) { if (rec.type.indexOf("wig") === 0 || rec.type.indexOf("bigWig") === 0 || id === "wikiTrack") { displayItemFunctions = false; } else if (rec.type.indexOf("expRatio") === 0) { displayItemFunctions = title !== "zoomInMore"; } else { displayItemFunctions = true; } // For barChart mouseovers, replace title (which may be a category // name+value) with item name if (rec.type.indexOf("barChart") === 0 @@ -3190,31 +3218,31 @@ } o[rightClick.makeImgTag("dnaIcon.png")+" Get DNA for "+title] = { onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, "getDna"); return true; } }; } o[rightClick.makeImgTag("bookOut.png")+ " Open details page in new window..."] = { onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, "openLink"); return true; } }; any = true; } - if (href && href.length > 0) { + if (href && href.length > 0 && href.indexOf("i=mergedItem") === -1) { // Add "Show details..." item if (title.indexOf("Click to alter ") === 0) { // suppress the "Click to alter..." items } else if (rightClick.selectedMenuItem.href.indexOf("cgi-bin/hgTracks") !== -1) { // suppress menu items for hgTracks links (e.g. Next/Prev map items). } else { var item; if (title === "zoomInMore") // avoid showing menu item that says // "Show details for zoomInMore..." (redmine 2447) item = rightClick.makeImgTag("book.png") + " Show details..."; else item = rightClick.makeImgTag("book.png")+" Show details for "+ title + "..."; @@ -3260,30 +3288,45 @@ o[rightClick.makeImgTag("folderWrench.png")+" Configure "+rec.shortLabel + " track set..."] = { onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, "hgTrackUi_follow"); return true; } }; } if (jQuery.floatMgr) { o[(rightClick.selectedMenuItem.id === rightClick.floatingMenuItem ? selectedImg : blankImg) + " float"] = { onclick: function(menuItemClicked, menuObject) { rightClick.hit(menuItemClicked, menuObject, "float"); return true; } }; } + // add a toggle to hide/show the merged item(s) + mergeTrack = rightClick.selectedMenuItem.id + ".doMergeItems"; + if (rec.hasOwnProperty(mergeTrack)) { + var hasMergedItems = rec[mergeTrack] === 1; + titleStr = rightClick.makeImgTag("wrench.png") + " "; + if (hasMergedItems) { + titleStr += "Show merged items"; + } else { + titleStr += "Merge items that span the current region"; + } + o[titleStr] = {onclick: function(menuItemClick, menuObject) { + rightClick.hit(menuItemClick, menuObject, "toggleMerge", rec); + return true; } + }; + } menu.push($.contextMenu.separator); menu.push(o); } menu.push($.contextMenu.separator); if (hgTracks.highlight && rightClick.clickedHighlightIdx!==null) { if (hgTracks.highlight.search(getDb() + '.') === 0) { var currentlySeen = ($('#highlightItem').length > 0); o = {}; // Jumps to highlight when not currently seen in image var text = (currentlySeen ? " Zoom" : " Jump") + " to highlight"; o[rightClick.makeImgTag("highlightZoom.png") + text] = { onclick: rightClick.makeHitCallback('jumpToHighlight') };