UNPKG

ideogram

Version:

Chromosome visualization for the web

192 lines (161 loc) 5.37 kB
/** * @fileoverview Functions for collinear chromosomes. * Collinear chromosomes form a line together, unlike the default parallel * geometry. */ import {d3} from './lib'; import collinearizeVerticalChromosomes from './collinear-vertical'; function labelGenomes(ideo) { ideo.config.taxids.forEach((taxid, i) => { var org = ideo.organisms[taxid]; var config = ideo.config; // var commonName = slug(org.commonName); var scientificName = org.scientificName; d3.select(ideo.selector) .append('text') .attr('class', 'genomeLabel italic') .attr('x', 5) .attr('y', config.chrLabelSize + (200 + (3 * config.chrWidth)) * i) .text(scientificName); }); } /** * Rearrange chromosomes from parallel horizontal to collinear horizontal * * Parallel horizontal (as in https://eweitz.github.io/ideogram/mouse) * --- * --- * --- * * Collinear horizontal (as in https://eweitz.github.io/ideogram/geometry-collinear): * --- --- --- */ function rearrangeChromosomes(chrSets, xOffsets, y, ideo) { var i, chr, chrSet, taxid, x, adjustedY, orgIndex, chrLabelY, config = ideo.config, chrWidth = config.chrWidth, chrLabelSize = config.chrLabelSize; for (i = 0; i < chrSets.length; i++) { chrSet = chrSets[i]; x = xOffsets[i]; chr = ideo.chromosomesArray[i]; taxid = chr.id.split('-')[1]; orgIndex = config.taxids.indexOf(taxid); adjustedY = y + orgIndex * 200; if (orgIndex === 0 && ideo.config.multiorganism) { chrLabelY = chrLabelSize - 4; adjustedY += chrWidth * 2 + chrLabelSize; } else { chrLabelY = chrWidth * 2 + chrLabelSize + 2; } if (ideo.config.showChromosomeLabels) { chrSet.querySelector('.chrLabel').setAttribute('y', chrLabelY); chrSet.querySelector('.chrLabel').setAttribute('text-anchor', 'middle'); } chrSet.setAttribute('transform', 'translate(' + x + ',' + adjustedY + ')'); chrSet.querySelector('.chromosome').setAttribute( 'transform', 'translate(-13, 10)' ); } if (config.multiorganism) { labelGenomes(ideo); } } /** * Get pixel coordinates to use for rearrangement */ function getXOffsets(chrSets, ideo) { var xOffsets, i, index, chr, prevChr, x, prevWidth, prevX, xBump, taxid, seenTaxids = {}; xOffsets = []; for (i = 0; i < chrSets.length; i++) { chr = ideo.chromosomesArray[i]; taxid = chr.id.split('-')[1]; index = (i === 0) ? i : i - 1; prevChr = ideo.chromosomesArray[index]; if (i === 0 || taxid in seenTaxids === false) { x = 20; seenTaxids[taxid] = 1; } else { prevWidth = prevChr.width; prevX = xOffsets[index]; xBump = (ideo.config.showChromosomeLabels ? 0 : 2); x = prevX + prevWidth + xBump + ideo.config.chrMargin; } xOffsets.push(x); } return xOffsets; } // /** // * Track number of chromosomes in preceding organisms. // * Adds an instance variable to the ideogram object to offset // * chromosome indices. Needed for multiorganism collinear ideograms. // */ // function setTaxidChrOffsets(ideo) { // var taxidChrOffsets, taxidChrOffset; // taxidChrOffsets = {}; // taxidChrOffset = 0; // ideo.config.organism.forEach((org) => { // var taxid, numChrs; // taxid = ideo.getTaxid(org); // taxidChrOffsets[taxid] = taxidChrOffset; // numChrs = Object.keys(ideo.chromosomes[taxid]).length; // taxidChrOffset += numChrs; // }); // ideo.taxidChrOffsets = taxidChrOffsets; // } // /** // * Change chromosome indices for multiorganism collinear ideograms // * This is needed to account for x-offsets. // */ // function adjustChrIndex(ideo) { // setTaxidChrOffsets(ideo); // ideo.chromosomesArray.map((chr) => { // var taxid = chr.id.split('-')[1]; // var taxidChrOffset = ideo.taxidChrOffsets[taxid]; // chr.chrIndex -= taxidChrOffset; // ideo.chromosomes[taxid][chr.name].chrIndex = chr.chrIndex; // }); // } function collinearizeChromosomes(ideo) { var chrSets, xOffsets, y, height, width, config = ideo.config, annotHeight = config.annotationHeight || 0; if (config.orientation === 'vertical') { collinearizeVerticalChromosomes(ideo); return; } // if (config.multiorganism) adjustChrIndex(ideo); ideo.config.annotLabelHeight = 12; var annotLabelHeight = ideo.config.annotLabelHeight; if ('demarcateCollinearChromosomes' in ideo.config === false) { ideo.config.demarcateCollinearChromosomes = true; } chrSets = document.querySelectorAll('.chromosome-set'); y = ( (config.numAnnotTracks * (annotHeight + annotLabelHeight + 4)) - config.chrWidth + 1 ); xOffsets = getXOffsets(chrSets, ideo); rearrangeChromosomes(chrSets, xOffsets, y, ideo); height = y + config.chrWidth * 2 + 20; if (config.multiorganism) { height *= 8; var maxWidth = 0; xOffsets.forEach(d => { if (d > maxWidth) maxWidth = d; }); width = maxWidth + 20; } else { width = xOffsets.slice(-1)[0] + 20; } d3.select(ideo.selector) .attr('width', width) .attr('height', height); d3.select('#_ideogramTrackLabelContainer').remove(); d3.select('#_ideogramInnerWrap') .insert('div', ':first-child') .attr('id', '_ideogramTrackLabelContainer') .style('position', 'absolute'); } export default collinearizeChromosomes;