UNPKG

@jbrowse/core

Version:

JBrowse 2 core libraries used by plugins

101 lines (100 loc) 5.01 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.default = calculateDynamicBlocks; const mobx_state_tree_1 = require("mobx-state-tree"); const _1 = require("."); const blockTypes_1 = require("./blockTypes"); const range_1 = require("./range"); function calculateDynamicBlocks(model, padding = true, elision = true) { const { offsetPx, displayedRegions, bpPerPx, width, minimumBlockWidth, interRegionPaddingWidth, } = model; if (!width) { throw new Error('view has no width, cannot calculate displayed blocks'); } const blocks = new blockTypes_1.BlockSet(); let displayedRegionLeftPx = 0; const windowLeftPx = offsetPx; const windowRightPx = windowLeftPx + width; for (let regionNumber = 0; regionNumber < displayedRegions.length; regionNumber++) { const region = displayedRegions[regionNumber]; const { assemblyName, refName, start: regionStart, end: regionEnd, reversed, } = region; const displayedRegionRightPx = displayedRegionLeftPx + (regionEnd - regionStart) / bpPerPx; const regionWidthPx = (regionEnd - regionStart) / bpPerPx; const parentRegion = (0, mobx_state_tree_1.isStateTreeNode)(region) ? (0, mobx_state_tree_1.getSnapshot)(region) : region; const [leftPx, rightPx] = (0, range_1.intersection2)(windowLeftPx, windowRightPx, displayedRegionLeftPx, displayedRegionRightPx); if (leftPx !== undefined && rightPx !== undefined) { let start; let end; let isLeftEndOfDisplayedRegion; let isRightEndOfDisplayedRegion; let blockOffsetPx; if (reversed) { start = Math.max(regionStart, regionEnd - (rightPx - displayedRegionLeftPx) * bpPerPx); end = regionEnd - (leftPx - displayedRegionLeftPx) * bpPerPx; isLeftEndOfDisplayedRegion = end === regionEnd; isRightEndOfDisplayedRegion = start === regionStart; blockOffsetPx = displayedRegionLeftPx + (regionEnd - end) / bpPerPx; } else { start = (leftPx - displayedRegionLeftPx) * bpPerPx + regionStart; end = Math.min(regionEnd, (rightPx - displayedRegionLeftPx) * bpPerPx + regionStart); isLeftEndOfDisplayedRegion = start === regionStart; isRightEndOfDisplayedRegion = end === regionEnd; blockOffsetPx = displayedRegionLeftPx + (start - regionStart) / bpPerPx; } const widthPx = (end - start) / bpPerPx; const blockData = { assemblyName, refName, start, end, reversed, offsetPx: blockOffsetPx, parentRegion, regionNumber, widthPx, isLeftEndOfDisplayedRegion, isRightEndOfDisplayedRegion, key: '', }; blockData.key = `${(0, _1.assembleLocStringFast)(blockData)}-${regionNumber}${reversed ? '-reversed' : ''}`; if (padding && blocks.length === 0 && isLeftEndOfDisplayedRegion) { blocks.push(new blockTypes_1.InterRegionPaddingBlock({ key: `${blockData.key}-beforeFirstRegion`, widthPx: -offsetPx, offsetPx: blockData.offsetPx + offsetPx, variant: 'boundary', })); } if (elision && regionWidthPx < minimumBlockWidth) { blocks.push(new blockTypes_1.ElidedBlock(blockData)); } else { blocks.push(new blockTypes_1.ContentBlock(blockData)); } if (padding) { if (regionWidthPx >= minimumBlockWidth && blockData.isRightEndOfDisplayedRegion && regionNumber < displayedRegions.length - 1) { blocks.push(new blockTypes_1.InterRegionPaddingBlock({ key: `${blockData.key}-rightpad`, widthPx: interRegionPaddingWidth, offsetPx: blockData.offsetPx + blockData.widthPx, })); displayedRegionLeftPx += interRegionPaddingWidth; } if (regionNumber === displayedRegions.length - 1 && blockData.isRightEndOfDisplayedRegion) { blockOffsetPx = blockData.offsetPx + blockData.widthPx; blocks.push(new blockTypes_1.InterRegionPaddingBlock({ key: `${blockData.key}-afterLastRegion`, widthPx: width - blockOffsetPx + offsetPx, offsetPx: blockOffsetPx, variant: 'boundary', })); } } } displayedRegionLeftPx += (regionEnd - regionStart) / bpPerPx; } return blocks; }