2a399cf9c25667374836901d6d6367a7d0fefe6c larrym Mon Feb 7 17:31:17 2011 -0800 add zoomToCodon code (redmine# 2724); this is currently turned off via the supportZoomCodon variable diff --git src/hg/js/hgTracks.js src/hg/js/hgTracks.js index 0742fae..b964606 100644 --- src/hg/js/hgTracks.js +++ src/hg/js/hgTracks.js @@ -14,30 +14,31 @@ var imageV2 = false; var imgBoxPortal = false; var blockUseMap = false; var mapItems; var trackImg; // jQuery element for the track image var trackImgTbl; // jQuery element used for image table under imageV2 var imgAreaSelect; // jQuery element used for imgAreaSelect var originalImgTitle; var autoHideSetting = true; // Current state of imgAreaSelect autoHide setting var selectedMenuItem; // currently choosen context menu item (via context menu). var browser; // browser ("msie", "safari" etc.) var mapIsUpdateable = true; var currentMapItem; var floatingMenuItem; var visibilityStrsOrder = new Array("hide", "dense", "full", "pack", "squish"); // map browser numeric visibility codes to strings +var supportZoomCodon = false; function initVars(img) { // There are various entry points, so we call initVars in several places to make sure this variables get updated. if(!originalPosition) { // remember initial position and size so we can restore it if user cancels originalPosition = getOriginalPosition(); originalSize = $('#size').text(); originalCursor = jQuery('body').css('cursor'); } } function selectStart(img, selection) { initVars(); @@ -1471,36 +1472,36 @@ // XXXX Is rightclick logic necessary? var rightclick = e.which ? (e.which == 3) : (e.button == 2); if(rightclick) { return false; } else { var o = findMapItem(e); if(o) { // XXXX Why does href get changed to "about://" on IE? window.location = o.href; } return true; } } -function contextMenuHit(menuItemClicked, menuObject, cmd) +function contextMenuHit(menuItemClicked, menuObject, cmd, args) { - setTimeout(function() { contextMenuHitFinish(menuItemClicked, menuObject, cmd); }, 1); + setTimeout(function() { contextMenuHitFinish(menuItemClicked, menuObject, cmd, args); }, 1); } -function contextMenuHitFinish(menuItemClicked, menuObject, cmd) +function contextMenuHitFinish(menuItemClicked, menuObject, cmd, args) { // dispatcher for context menu hits var id = selectedMenuItem.id; if(menuObject.shown) { // showWarning("Spinning: menu is still shown"); setTimeout(function() { contextMenuHitFinish(menuItemClicked, menuObject, cmd); }, 10); return; } if(cmd == 'selectWholeGene' || cmd == 'getDna') { // bring whole gene into view or redirect to DNA screen. var href = selectedMenuItem.href; var chromStart, chromEnd; var a = /hgg_chrom=(\w+)&/.exec(href); // Many links leave out the chrom (b/c it's in the server side cart as "c") var chrom = document.getElementById("hgt.chromName").value; @@ -1550,30 +1551,53 @@ jQuery('body').css('cursor', ''); $.ajax({ type: "GET", url: "../cgi-bin/hgTracks", data: "hgt.trackImgOnly=1&hgt.ideogramToo=1&position=" + newPosition + "&hgsid=" + getHgsid(), dataType: "html", trueSuccess: handleUpdateTrackMap, success: catchErrorOrDispatch, error: errorHandler, cmd: cmd, cache: false }); } } } + } else if (cmd == 'zoomCodon' || cmd == 'zoomExon') { + var num, ajaxCmd, errorMsg; + if(cmd == 'zoomCodon') { + num = prompt("Please enter the codon number to jump to:"); + ajaxCmd = 'codonPos'; + errorMsg = num + " is an invalid codon for this gene"; + } else { + num = prompt("Please enter the exon number to jump to:"); + ajaxCmd = 'exonPos'; + errorMsg = num + " is an invalid exon number for this gene"; + } + if(num) { + $.ajax({ + type: "GET", + url: "../cgi-bin/hgApi", + data: "db=" + getDb() + "&cmd=" + ajaxCmd + "&num=" + num + "&table=" + args.table + "&name=" + args.name, + trueSuccess: handleZoomCodon, + success: catchErrorOrDispatch, + error: errorHandler, + errorMsg: errorMsg, + cache: true + }); + } } else if (cmd == 'hgTrackUi_popup') { hgTrackUiPopUp( selectedMenuItem.id, false ); // Launches the popup but shields the ajax with a waitOnFunction } else if (cmd == 'hgTrackUi_follow') { var url = "hgTrackUi?hgsid=" + getHgsid() + "&g="; var rec = trackDbJson[id]; if (tdbHasParent(rec) && tdbIsLeaf(rec)) url += rec.parentTrack else { var link = $( 'td#td_btn_'+ selectedMenuItem.id ).children('a'); // The button already has the ref if( $(link) != undefined) url = $(link).attr('href'); else @@ -1775,30 +1799,61 @@ var title = selectedMenuItem.title || "feature"; if(isGene || isHgc || id == "wikiTrack") { // 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; } } if(displayItemFunctions) { o[makeImgTag("magnify.png") + " Zoom to " + title] = {onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "selectWholeGene"); return true; }}; + if(supportZoomCodon && rec.type.indexOf("genePred") != -1) { + // http://hgwdev-larrym.cse.ucsc.edu/cgi-bin/hgGene?hgg_gene=uc003tqk.2&hgg_prot=P00533&hgg_chrom=chr7&hgg_start=55086724&hgg_end=55275030&hgg_type=knownGene&db=hg19&c=chr7 + var name, table; + var reg = new RegExp("hgg_gene=([^&]+)"); + var a = reg.exec(href); + if(a && a[1]) { + name = a[1]; + reg = new RegExp("hgg_type=([^&]+)"); + a = reg.exec(href); + if(a && a[1]) { + table = a[1]; + } + } else { + // http://hgwdev-larrym.cse.ucsc.edu/cgi-bin/hgc?o=55086724&t=55275031&g=refGene&i=NM_005228&c=chr7 + // http://hgwdev-larrym.cse.ucsc.edu/cgi-bin/hgc?o=55086713&t=55270769&g=wgEncodeGencodeManualV4&i=ENST00000455089&c=chr7 + var reg = new RegExp("i=([^&]+)"); + var a = reg.exec(href); + if(a && a[1]) { + name = a[1]; + reg = new RegExp("g=([^&]+)"); + a = reg.exec(href); + if(a && a[1]) { + table = a[1]; + } + } + } + if(name && table) { + o[makeImgTag("magnify.png") + " Zoom to codon"] = {onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "zoomCodon", {name: name, table: table}); return true; }}; + o[makeImgTag("magnify.png") + " Zoom to exon"] = {onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "zoomExon", {name: name, table: table}); return true; }}; + } + } o[makeImgTag("dnaIcon.png") + " Get DNA for " + title] = {onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "getDna"); return true; }}; } o[makeImgTag("bookOut.png") + " Open details page in new window..."] = {onclick: function(menuItemClicked, menuObject) { contextMenuHit(menuItemClicked, menuObject, "openLink"); return true; }}; any = true; } if(href != undefined && href.length > 0) { // Add "Show details..." item if(title.indexOf("Click to alter ") == 0) { ; // suppress the "Click to alter..." items } else if(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) @@ -2710,15 +2765,29 @@ selectUpdated = true; }); if(rec) { rec.localVisibility = visibility; } return selectUpdated; } function reloadFloatingItem() { // currently dead (experimental code) if(floatingMenuItem) { $('#img_data_' + floatingMenuItem).parent().makeFloat({x:"current",y:"current", speed: 'fast', alwaysVisible: true, alwaysTop: true}); } } + +function handleZoomCodon(response, status) +{ + // XXXX use formal json interface + if(response.length > 1) { + setPosition(response, 3); + if(document.TrackForm) + document.TrackForm.submit(); + else + document.TrackHeaderForm.submit(); + } else { + alert(this.errorMsg); + } +}