import { linearTransform } from '../../../utils/coordinates'; import { parseHex, zeroPadHex } from '../../../utils/colors'; import { SNP, RenderedSNP, RenderedSNPs, Path, LD } from './types'; export function renderSNPs(snps: SNP[], highlighted: Set, x: (value: number) => number, hColor: string, color: string): RenderedSNPs { const coords: Map = new Map(); const results: RenderedSNP[] = []; snps.sort( (a, b) => a.domain.start - b.domain.start ).forEach( snp => { const taller = highlighted.has(snp.id); const t = taller ? 2 : 1; const start = x(snp.domain.start); const end = x(snp.domain.end) - start < t ? start + t : x(snp.domain.end); const lend = results[results.length - 1] && results[results.length - 1].domain.end; coords.set(snp.id, (end + start) / 2); if (lend && lend > start) { results[results.length - 1].domain.end = end; if (taller) { results[results.length - 1].taller = true; results[results.length - 1].color = hColor; } } else results.push({ ...snp, domain: { start, end }, color: taller ? hColor : color, taller }); }); return { snps: results, coords }; } export function renderLD(coords: Map, anchor: string, ld: LD[], x: (value: number) => number, ldThreshold: number, height: number): Path[] { const anchorx = coords.get(anchor); const c = (snp: LD) => x((snp.coordinates.start + snp.coordinates.end) / 2); const cx = linearTransform({ start: ldThreshold, end: 1.0 }, { start: parseHex("0000ED"), end: parseHex("000000") }); if (anchorx === undefined) return []; return ld.filter(snp => snp.rSquared > ldThreshold).map( (snp: LD): Path => ({ d: `M ${anchorx} ${height * 0.7} Q ${(anchorx + c(snp)) / 2} 0 ${c(snp)} ${height * 0.7}`, stroke: `#FF${zeroPadHex(Math.floor(cx(snp.rSquared)))}00` })); }