@jbrowse/core
Version:
JBrowse 2 core libraries used by plugins
101 lines (100 loc) • 5.01 kB
JavaScript
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;
}
;