UNPKG

@jbrowse/core

Version:

JBrowse 2 core libraries used by plugins

199 lines (198 loc) 6.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.moveTo = moveTo; exports.pxToBp = pxToBp; exports.bpToPx = bpToPx; exports.bpToPxMap = bpToPxMap; function lengthBetween(self, start, end) { let bpSoFar = 0; const { displayedRegions } = self; if (start.index === end.index) { bpSoFar += end.offset - start.offset; } else { const s = displayedRegions[start.index]; bpSoFar += s.end - s.start - start.offset; if (end.index - start.index >= 2) { for (let i = start.index + 1; i < end.index; i++) { const region = displayedRegions[i]; const len = region.end - region.start; bpSoFar += len; } } bpSoFar += end.offset; } return bpSoFar; } function moveTo(self, start, end) { if (!start || !end) { return; } const { width, interRegionPaddingWidth, displayedRegions, bpPerPx, minimumBlockWidth, } = self; const len = lengthBetween(self, start, end); let numBlocksWideEnough = 0; for (let i = start.index; i < end.index; i++) { const r = displayedRegions[i]; if ((r.end - r.start) / bpPerPx > minimumBlockWidth) { numBlocksWideEnough++; } } const targetBpPerPx = len / (width - interRegionPaddingWidth * numBlocksWideEnough); const newBpPerPx = self.zoomTo(targetBpPerPx); let extraBp = 0; if (targetBpPerPx < newBpPerPx) { extraBp = ((newBpPerPx - targetBpPerPx) * self.width) / 2; } let bpToStart = -extraBp; for (let i = 0; i < self.displayedRegions.length; i++) { const region = self.displayedRegions[i]; if (start.index === i) { bpToStart += start.offset; break; } else { bpToStart += region.end - region.start; } } self.scrollTo(Math.round(bpToStart / self.bpPerPx)); } function coord(r, bp) { return Math.floor(r.reversed ? r.end - bp : r.start + bp) + 1; } function pxToBp(self, px) { var _a; let bpSoFar = 0; const { bpPerPx, offsetPx, displayedRegions, interRegionPaddingWidth, staticBlocks, } = self; const blocks = staticBlocks.contentBlocks; const bp = (offsetPx + px) * bpPerPx; if (bp < 0) { const r = displayedRegions[0]; const snap = r; return { ...snap, oob: true, coord: coord(r, bp), offset: bp, index: 0, }; } const interRegionPaddingBp = interRegionPaddingWidth * bpPerPx; let currBlock = 0; for (let i = 0; i < displayedRegions.length; i++) { const r = displayedRegions[i]; const len = r.end - r.start; const offset = bp - bpSoFar; if (len + bpSoFar > bp && bpSoFar <= bp) { const snap = r; return { ...snap, oob: false, offset, coord: coord(r, offset), index: i, }; } if (((_a = blocks[currBlock]) === null || _a === void 0 ? void 0 : _a.regionNumber) === i) { bpSoFar += len + interRegionPaddingBp; currBlock++; } else { bpSoFar += len; } } if (bp >= bpSoFar && displayedRegions.length > 0) { const r = displayedRegions.at(-1); const len = r.end - r.start; const offset = bp - bpSoFar + len; const snap = r; return { ...snap, oob: true, offset, coord: coord(r, offset), index: displayedRegions.length - 1, }; } return { coord: 0, index: 0, refName: '', oob: true, assemblyName: '', offset: 0, start: 0, end: 0, reversed: false, }; } function bpToPx({ refName, coord, regionNumber, self, }) { var _a; let bpSoFar = 0; const { interRegionPaddingWidth, bpPerPx, displayedRegions, staticBlocks } = self; const blocks = staticBlocks.contentBlocks; const interRegionPaddingBp = interRegionPaddingWidth * bpPerPx; let currBlock = 0; let i = 0; for (; i < displayedRegions.length; i++) { const r = displayedRegions[i]; const len = r.end - r.start; if (refName === r.refName && coord >= r.start && coord <= r.end && (regionNumber ? regionNumber === i : true)) { bpSoFar += r.reversed ? r.end - coord : coord - r.start; break; } if (((_a = blocks[currBlock]) === null || _a === void 0 ? void 0 : _a.regionNumber) === i) { bpSoFar += len + interRegionPaddingBp; currBlock++; } else { bpSoFar += len; } } const found = displayedRegions[i]; if (found) { return { index: i, offsetPx: Math.round(bpSoFar / bpPerPx), }; } return undefined; } function bpToPxMap({ refName, coord, regionNumber, self, }) { var _a; let bpSoFar = 0; const { interRegionPaddingWidth, bpPerPx, displayedRegions, staticBlocks } = self; const blocks = staticBlocks.contentBlocks; const interRegionPaddingBp = interRegionPaddingWidth * bpPerPx; const map = {}; let currBlock = 0; let i = 0; for (; i < displayedRegions.length; i++) { const r = displayedRegions[i]; const len = r.end - r.start; if (refName === r.refName && coord >= r.start && coord <= r.end && (regionNumber === undefined ? true : regionNumber === i)) { bpSoFar += r.reversed ? r.end - coord : coord - r.start; break; } if (((_a = blocks[currBlock]) === null || _a === void 0 ? void 0 : _a.regionNumber) === i) { bpSoFar += len + interRegionPaddingBp; currBlock++; } else { bpSoFar += len; } } const found = displayedRegions[i]; if (found) { return { index: i, offsetPx: Math.round(bpSoFar / bpPerPx), }; } return map; }