UNPKG

ideogram

Version:

Chromosome visualization with D3.js

104 lines (87 loc) 2.93 kB
/** * @fileoverview Methods to convert to and from different types of coordinates. * * Ideogram.js uses multiple coordinate systems, e.g. base pairs (bp) and * pixels (px). These methods interconvert between those coordinate systems. * * TODO: * - Add methods to interconvert between ISCN coordinates and base pairs, * pixels. */ /** * Converts base pair coordinates to pixel offsets. * Bp-to-pixel scales differ among cytogenetic bands. * * For example, if we want to depict a gene on a chromosome, then we need * to convert the gene's location in base pairs to a location in pixels offset * from the start of the chromosome. */ function convertBpToPx(chr, bp) { var i, band, bpToIscnScale, iscn, px, pxStart, pxLength, iscnStart, iscnStop, iscnLength, bpStart, bpStop, bpLength; if (chr.bands.length > 1) { for (i = 0; i < chr.bands.length; i++) { band = chr.bands[i]; bpStart = band.bp.start; bpStop = band.bp.stop; bpLength = bpStop - bpStart; iscnStart = band.iscn.start; iscnStop = band.iscn.stop; iscnLength = iscnStop - iscnStart; pxStart = band.px.start; pxLength = band.px.width; if (bp >= bpStart && bp <= bpStop) { bpToIscnScale = iscnLength / bpLength; iscn = iscnStart + (bp - bpStart) * bpToIscnScale; px = pxStart + (pxLength * (iscn - iscnStart) / (iscnLength)); return px; } } } else { pxLength = chr.width; if (bp >= 1 && bp <= chr.length) { px = chr.scale.bp * bp; return px; } } throw new Error( 'Base pair out of range. ' + 'bp: ' + bp + '; length of chr' + chr.name + ': ' + band.bp.stop ); } /** * Converts pixel offsets to base pair coordinates. * Pixel-to-bp scales differ among cytogenetic bands. * * For example, if we want to determine the genomic location a user clicked on * (e.g. when creating a brush / sliding window region), then we need to * convert pixels to base pairs. */ function convertPxToBp(chr, px) { var i, band, pxToIscnScale, iscn, bp, pxLength, pxStart, pxStop, iscnStart, iscnStop, bpLength, iscnLength; if (px === 0) { px = chr.bands[0].px.start; } for (i = 0; i < chr.bands.length; i++) { band = chr.bands[i]; pxStart = band.px.start; pxStop = band.px.stop; iscnStart = band.iscn.start; iscnStop = band.iscn.stop; if (px >= pxStart && px <= pxStop) { iscnLength = iscnStop - iscnStart; pxLength = pxStop - pxStart; bpLength = band.bp.stop - band.bp.start; pxToIscnScale = iscnLength / pxLength; iscn = iscnStart + (px - pxStart) * pxToIscnScale; bp = band.bp.start + (bpLength * (iscn - iscnStart) / iscnLength); return Math.round(bp); } } throw new Error( 'Pixel out of range. ' + 'px: ' + px + '; length of chr' + chr.name + ': ' + pxStop ); } export {convertBpToPx, convertPxToBp};