UNPKG

@jbrowse/plugin-wiggle

Version:

JBrowse 2 wiggle adapters, tracks, etc.

156 lines (155 loc) 4.62 kB
import { readConfObject } from '@jbrowse/core/configuration'; import { scaleLinear, scaleLog, scaleQuantize, } from '@mui/x-charts-vendor/d3-scale'; export const YSCALEBAR_LABEL_OFFSET = 5; export const WIGGLE_COLOR_DEFAULT = '#f0f'; export function getColorCallback(config, opts) { const colorIsCallback = config.color?.isCallback; if (colorIsCallback) { return (feature) => readConfObject(config, 'color', { feature }); } const color = readConfObject(config, 'color'); const colorIsDefault = color === WIGGLE_COLOR_DEFAULT; if (!colorIsDefault) { return () => color; } if (opts?.defaultColor) { return () => opts.defaultColor; } const pivotValue = readConfObject(config, 'bicolorPivotValue'); const negColor = readConfObject(config, 'negColor'); const posColor = readConfObject(config, 'posColor'); return (_feature, score) => score < pivotValue ? negColor : posColor; } export function getScale({ domain, range, scaleType, pivotValue, inverted, }) { let scale; const [min, max] = domain; if (min === undefined || max === undefined) { throw new Error('invalid domain'); } if (scaleType === 'linear') { scale = scaleLinear(); } else if (scaleType === 'log') { scale = scaleLog().base(2); } else if (scaleType === 'quantize') { scale = scaleQuantize(); } else { throw new Error('undefined scaleType'); } scale.domain(pivotValue !== undefined ? [min, pivotValue, max] : [min, max]); scale.nice(); const [rangeMin, rangeMax] = range; if (rangeMin === undefined || rangeMax === undefined) { throw new Error('invalid range'); } scale.range(inverted ? range.slice().reverse() : range); return scale; } export function getOrigin(scaleType) { if (scaleType === 'log') { return 1; } return 0; } export function getNiceDomain({ scaleType, domain, bounds, }) { const [minScore, maxScore] = bounds; let [min, max] = domain; if (scaleType === 'linear') { if (max < 0) { max = 0; } if (min > 0) { min = 0; } } if (scaleType === 'log') { if (min >= 0 && max > 1) { min = 1; } } if (minScore !== undefined && minScore !== Number.MIN_VALUE) { min = minScore; } if (maxScore !== undefined && maxScore !== Number.MAX_VALUE) { max = maxScore; } const getScaleType = (type) => { if (type === 'linear') { return scaleLinear(); } if (type === 'log') { const scale = scaleLog(); scale.base(2); return scale; } if (type === 'quantize') { return scaleQuantize(); } throw new Error(`undefined scaleType ${type}`); }; const scale = getScaleType(scaleType); scale.domain([min, max]); scale.nice(); return scale.domain(); } export function toP(s = 0) { return +s.toPrecision(6); } export function serializeWiggleFeature(f) { return { uniqueId: f.id(), start: f.get('start'), end: f.get('end'), score: f.get('score'), source: f.get('source'), refName: f.get('refName'), maxScore: f.get('maxScore'), minScore: f.get('minScore'), summary: f.get('summary'), }; } export function round(value) { return Math.round(value * 1e5) / 1e5; } export const WIGGLE_FUDGE_FACTOR = 0.3; export const WIGGLE_CLIP_HEIGHT = 2; export function getScaleValues(scaleOpts, height) { const scale = getScale({ ...scaleOpts, range: [0, height] }); const domain = scale.domain(); const niceMin = domain[0]; const niceMax = domain[1]; const domainSpan = niceMax - niceMin; const isLog = scaleOpts.scaleType === 'log'; const linearRatio = domainSpan !== 0 ? height / domainSpan : 0; const log2 = Math.log(2); const logMin = Math.log(niceMin) / log2; const logMax = Math.log(niceMax) / log2; const logSpan = logMax - logMin; const logRatio = logSpan !== 0 ? height / logSpan : 0; return { niceMin, niceMax, height, linearRatio, log2, logMin, logRatio, isLog, }; } export function fillRectCtx(x, y, width, height, ctx, color) { if (width < 0) { x += width; width = -width; } if (height < 0) { y += height; height = -height; } if (color) { ctx.fillStyle = color; } ctx.fillRect(x, y, width, height); }