@jbrowse/plugin-wiggle
Version:
JBrowse 2 wiggle adapters, tracks, etc.
82 lines (81 loc) • 3.5 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.drawDensity = drawDensity;
const configuration_1 = require("@jbrowse/core/configuration");
const util_1 = require("@jbrowse/core/util");
const stopToken_1 = require("@jbrowse/core/util/stopToken");
const util_2 = require("./util");
const fudgeFactor = 0.3;
const clipHeight = 2;
function drawDensity(ctx, props) {
const { stopToken, features, regions, bpPerPx, scaleOpts, height, config } = props;
const region = regions[0];
const pivot = (0, configuration_1.readConfObject)(config, 'bicolorPivot');
const pivotValue = (0, configuration_1.readConfObject)(config, 'bicolorPivotValue');
const negColor = (0, configuration_1.readConfObject)(config, 'negColor');
const posColor = (0, configuration_1.readConfObject)(config, 'posColor');
const color = (0, configuration_1.readConfObject)(config, 'color');
const clipColor = (0, configuration_1.readConfObject)(config, 'clipColor');
const crossing = pivot !== 'none' && scaleOpts.scaleType !== 'log';
const scale = (0, util_2.getScale)({
...scaleOpts,
pivotValue: crossing ? pivotValue : undefined,
range: crossing ? [negColor, '#eee', posColor] : ['#eee', posColor],
});
const scale2 = (0, util_2.getScale)({ ...scaleOpts, range: [0, height] });
const cb = color === '#f0f'
? (_, score) => scale(score)
: (feature, score) => (0, configuration_1.readConfObject)(config, 'color', { feature, score });
const domain = scale2.domain();
const niceMin = domain[0];
const niceMax = domain[1];
let prevLeftPx = Number.NEGATIVE_INFINITY;
let hasClipping = false;
const reducedFeatures = [];
let start = performance.now();
for (const feature of features.values()) {
if (performance.now() - start > 400) {
(0, stopToken_1.checkStopToken)(stopToken);
start = performance.now();
}
const [leftPx, rightPx] = (0, util_1.featureSpanPx)(feature, region, bpPerPx);
if (Math.floor(leftPx) !== Math.floor(prevLeftPx) || rightPx - leftPx > 1) {
reducedFeatures.push(feature);
prevLeftPx = leftPx;
}
const score = feature.get('score');
hasClipping = hasClipping || score > niceMax || score < niceMin;
const w = rightPx - leftPx + fudgeFactor;
if (score >= scaleOpts.domain[0]) {
ctx.fillStyle = cb(feature, score);
ctx.fillRect(leftPx, 0, w, height);
}
else {
ctx.fillStyle = '#eee';
ctx.fillRect(leftPx, 0, w, height);
}
}
ctx.save();
if (hasClipping) {
ctx.fillStyle = clipColor;
for (const feature of features.values()) {
if (performance.now() - start > 400) {
(0, stopToken_1.checkStopToken)(stopToken);
start = performance.now();
}
const [leftPx, rightPx] = (0, util_1.featureSpanPx)(feature, region, bpPerPx);
const w = rightPx - leftPx + fudgeFactor;
const score = feature.get('score');
if (score > niceMax) {
(0, util_2.fillRectCtx)(leftPx, 0, w, clipHeight, ctx);
}
else if (score < niceMin && scaleOpts.scaleType !== 'log') {
(0, util_2.fillRectCtx)(leftPx, 0, w, clipHeight, ctx);
}
}
}
ctx.restore();
return {
reducedFeatures,
};
}