@jbrowse/core
Version:
JBrowse 2 core libraries used by plugins
103 lines (102 loc) • 5.02 kB
JavaScript
Object.defineProperty(exports, "__esModule", { value: true });
exports.default = calculateStaticBlocks;
const mobx_state_tree_1 = require("mobx-state-tree");
const _1 = require(".");
const blockTypes_1 = require("./blockTypes");
function calculateStaticBlocks(model, padding = true, elision = true, extra = 0, width = 800) {
const { offsetPx, displayedRegions, bpPerPx, minimumBlockWidth, interRegionPaddingWidth, width: modelWidth, } = model;
const windowLeftBp = offsetPx * bpPerPx;
const windowRightBp = (offsetPx + modelWidth) * bpPerPx;
const blockSizePx = width;
const blockSizeBp = Math.ceil(blockSizePx * bpPerPx);
let regionBpOffset = 0;
const blocks = new blockTypes_1.BlockSet();
for (let regionNumber = 0; regionNumber < displayedRegions.length; regionNumber++) {
const region = displayedRegions[regionNumber];
const { assemblyName, refName, start: regionStart, end: regionEnd, reversed, } = region;
const regionBlockCount = Math.ceil((regionEnd - regionStart) / blockSizeBp);
const parentRegion = (0, mobx_state_tree_1.isStateTreeNode)(region) ? (0, mobx_state_tree_1.getSnapshot)(region) : region;
let windowRightBlockNum = Math.floor((windowRightBp - regionBpOffset) / blockSizeBp) + extra;
if (windowRightBlockNum >= regionBlockCount) {
windowRightBlockNum = regionBlockCount - 1;
}
let windowLeftBlockNum = Math.floor((windowLeftBp - regionBpOffset) / blockSizeBp) - extra;
if (windowLeftBlockNum < 0) {
windowLeftBlockNum = 0;
}
const regionWidthPx = (regionEnd - regionStart) / bpPerPx;
for (let blockNum = windowLeftBlockNum; blockNum <= windowRightBlockNum; blockNum += 1) {
let start;
let end;
let isLeftEndOfDisplayedRegion;
let isRightEndOfDisplayedRegion;
if (reversed) {
start = Math.max(regionStart, regionEnd - (blockNum + 1) * blockSizeBp);
end = regionEnd - blockNum * blockSizeBp;
isLeftEndOfDisplayedRegion = end === regionEnd;
isRightEndOfDisplayedRegion = start === regionStart;
}
else {
start = regionStart + blockNum * blockSizeBp;
end = Math.min(regionEnd, regionStart + (blockNum + 1) * blockSizeBp);
isLeftEndOfDisplayedRegion = start === regionStart;
isRightEndOfDisplayedRegion = end === regionEnd;
}
const widthPx = (end - start) / bpPerPx;
const blockData = {
assemblyName,
refName,
start,
end,
reversed,
offsetPx: (regionBpOffset + blockNum * blockSizeBp) / bpPerPx,
parentRegion,
regionNumber,
widthPx,
isLeftEndOfDisplayedRegion,
isRightEndOfDisplayedRegion,
key: '',
};
blockData.key = `${(0, _1.assembleLocStringFast)(blockData)}-${regionNumber}${reversed ? '-reversed' : ''}`;
if (padding && regionNumber === 0 && blockNum === 0) {
blocks.push(new blockTypes_1.InterRegionPaddingBlock({
key: `${blockData.key}-beforeFirstRegion`,
widthPx: width,
offsetPx: blockData.offsetPx - width,
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) {
regionBpOffset += interRegionPaddingWidth * bpPerPx;
blocks.push(new blockTypes_1.InterRegionPaddingBlock({
key: `${blockData.key}-rightpad`,
widthPx: interRegionPaddingWidth,
offsetPx: blockData.offsetPx + blockData.widthPx,
}));
}
if (regionNumber === displayedRegions.length - 1 &&
blockData.isRightEndOfDisplayedRegion) {
regionBpOffset += interRegionPaddingWidth * bpPerPx;
blocks.push(new blockTypes_1.InterRegionPaddingBlock({
key: `${blockData.key}-afterLastRegion`,
widthPx: width,
offsetPx: blockData.offsetPx + blockData.widthPx,
variant: 'boundary',
}));
}
}
}
regionBpOffset += regionEnd - regionStart;
}
return blocks;
}
;