8c4510913f781693d99d967eed017e6909e13d4c angie Thu Apr 28 10:42:01 2016 -0700 Make sure we support mirrors that don't have all (or any) of our popular species. refs #15277 note 233 diff --git src/hg/js/hgGateway.js src/hg/js/hgGateway.js index 628bbf8..5e62a4c 100644 --- src/hg/js/hgGateway.js +++ src/hg/js/hgGateway.js @@ -333,30 +333,33 @@ // First see if there's already something there that we will replace: var oldG = svg.getElementById('hubsAndTree'); var newG = svgCreateEl('g', { id: 'hubsAndTree' }); // y offsets of tops of species labels (leaves of dbDbTree), filled in by drawNode. var leafTops = {}; var hubBottomY, treeInfo, width, height; if (! checkTree(dbDbTree)) { console.error('dbDbTree in wrong format', dbDbTree); return; } _.assign(cfg, cfgOverrides); hubBottomY = drawHubs(newG, hubList, cfg.labelStartY); addDepth(dbDbTree); treeInfo = drawNode(newG, dbDbTree, hubBottomY, leafTops); width = treeInfo.x + cfg.paddingRight; + if (width < cfg.containerWidth) { + width = cfg.containerWidth; + } height = treeInfo.leafY - cfg.labelLineHeight + cfg.paddingBottom; if (oldG) { svg.removeChild(oldG); } svg.appendChild(newG); return { width: width, height: height, yTree: hubBottomY - cfg.labelLineHeight, leafTops: leafTops }; } return { draw: draw }; }()); // speciesTree @@ -530,31 +533,30 @@ style: 'fill:' + color + '; stroke:' + color }); svg.appendChild(rect); } function drawStripes(svg, dbDbTree, yTop, height, leafTops) { var stripeCount = stripeColors.length; var lastStripeIx = stripeCount - 1; var stripeTops = []; var i, stripeHeight; findStripeTops(dbDbTree, lastStripeIx, leafTops, stripeTops, yTop); // Add an extra "stripe" coord so we have the coord for the bottom of the last stripe: stripeTops[stripeCount] = height; // Initialize missing stripes to 0-height (top = next stripe's top), if any: for (i = stripeCount - 1; i >= 0; i--) { if (stripeTops[i] === undefined) { - console.warn("No species found for stripe " + i + ", taxId " + stripeTaxIds[i]); stripeTops[i] = stripeTops[i+1]; } } for (i = 0; i < stripeCount; i++) { stripeHeight = stripeTops[i+1] - stripeTops[i]; addRectFill(svg, 0, stripeTops[i], cfg.stripeWidth, stripeHeight, stripeColors[i]); } // Add stripe for hubs, if any: if (yTop > 0) { addRectFill(svg, 0, 0, cfg.stripeWidth, yTop, hubColor); } return stripeTops; } function drawOneIcon(svg, name, y) { @@ -768,46 +770,58 @@ 'existing browser to ' + '' + ' FireFox or ' + '' + 'Chrome.' + '

'; // Globals (within this function scope) // Set this to true to see server requests and responses in the console. var debugCartJson = false; // This is a global (within wrapper function scope) so event handlers can use it // without needing to bind functions. var scrollbarWidth = 0; // This holds everything we need to know to draw the page: taxId, db, hubs, description etc. var uiState = {}; + // This is used to check whether a taxId is found in activeGenomes: + var activeTaxIds = _.invert(activeGenomes); // This is dbDbTree after pruning -- null if dbDbTree has no children left - var prunedDbDbTree; + var prunedDbDbTree = null; // This keeps track of which gene the user has selected most recently from autocomplete. var selectedGene = null; function setupFavIcons() { // Set up onclick handlers for shortcut buttons and labels + var haveIcon = false; var i, name, taxId, onClick; for (i = 0; i < favIconTaxId.length; i++) { name = favIconTaxId[i][0]; taxId = favIconTaxId[i][1]; + if (activeTaxIds[taxId]) { // When user clicks on icon, set the taxId (default database); // scroll the image to that species and clear the species autocomplete input. onClick = setTaxId.bind(null, taxId, null, true, true); // Onclick for both the icon and its sibling label: $('.jwIconSprite' + name).parent().children().click(onClick); + haveIcon = true; + } else { + // Inactive on this site -- hide it + $('.jwIconSprite' + name).parent().hide(); + } + } + if (! haveIcon) { + $('#popSpeciesTitle').text('Species Search'); } } function addCategory(cat, item) { // Clone item, add category: cat to it and return it (helper function, see below). var clone = {}; _.assign(clone, item, { category: cat }); return clone; } function autocompleteFromNode(node) { // Traverse dbDbTree to make autocomplete result lists for all non-leaf node labels. // Returns an object mapping each label of node and descendants to a list of // result objects with the same structure that we'd get from a server request. if (! node) { @@ -1093,31 +1107,32 @@ // Return true if some leaf descendant of node is in activeGenomes or activeTaxIds. // Remove any child that returns false. // If one of {genome, taxId} matches but not the other, tweak the other to match dbDb, // Since we'll be using the hgwdev dbDbTree on the RR which may have been tweaked. var genome = node[0], taxId = node[1], kids = node[3]; var hasActiveLeaf = false, i, dbDbTaxId, dbDbGenome; if (!kids || kids.length === 0) { // leaf node: is it active? dbDbTaxId = activeGenomes[genome]; if (dbDbTaxId) { hasActiveLeaf = true; node[1] = dbDbTaxId; } // Yet another special case for Baboon having one genome with two species... // maybe we should just change dbDb? - else if (_.startsWith(genome, 'Baboon ') && (taxId === 9555 || taxId === 9562)) { + else if (_.startsWith(genome, 'Baboon ') && (taxId === 9555 || taxId === 9562) && + activeGenomes.Baboon) { hasActiveLeaf = true; } else { dbDbGenome = activeTaxIds[taxId]; if (dbDbGenome) { hasActiveLeaf = true; node[0] = dbDbGenome; } } } else { // parent node: splice out any child nodes with no active leaves for (i = kids.length - 1; i >= 0; i--) { if (pruneInactive(kids[i], activeGenomes, activeTaxIds)) { hasActiveLeaf = true; } else { kids.splice(i, 1); @@ -1606,35 +1621,36 @@ } function init() { // Boot up the page; initialize elements and install event handlers. var searchObj = {}; // We need a bound function to pass into autocompleteCat.init below; // however, autocompleteFromTree is even slower than drawing the tree because of // all the copying. So bind now, fill in searchObj later. var processSpeciesResults = processSpeciesAutocompleteItems.bind(null, searchObj); cart.setCgi('hgGateway'); cart.debug(debugCartJson); // Get state from cart cart.send({ getUiState: {} }, handleRefreshState); cart.flush(); // Prune inactive genomes from dbDbTree. - var activeTaxIds = _.invert(activeGenomes); + if (window.dbDbTree) { prunedDbDbTree = dbDbTree; - if (dbDbTree && ! pruneInactive(dbDbTree, activeGenomes, activeTaxIds)) { + if (! pruneInactive(dbDbTree, activeGenomes, activeTaxIds)) { prunedDbDbTree = null; } + } // When page has loaded, do layout adjustments and initialize event handlers. $(function() { scrollbarWidth = findScrollbarWidth(); setRightColumnWidth(); setupFavIcons(); autocompleteCat.init($('#speciesSearch'), { baseUrl: 'hgGateway?hggw_term=', watermark: speciesWatermark, onSelect: setDbFromAutocomplete, onServerReply: processSpeciesResults, enterSelectsIdentical: true }); $('#selectAssembly').change(onChangeDbMenu); $('#positionDisplay').click(onClickCopyPosition); $('#copyPosition').click(onClickCopyPosition);