import { Link, Rect, FilledPath } from "./types"; import { linearTransform } from "../../../utils/coordinates"; import { parseHex } from "../../../utils/colors"; import { Path } from "../ld/types"; export function renderRegions(links: Link[], x: (value: number) => number, color: string): Rect[] { return links.reduce( (clist, link) => ([ ...clist, { start: x(link.regionA.start), end: x(link.regionA.end), fill: color }, { start: x(link.regionB.start), end: x(link.regionB.end), fill: color } ]), []); } export function renderLinks(links: Link[], x: (value: number) => number, height: number, threshold: number): FilledPath[] { const cx = linearTransform({ start: threshold, end: Math.max(...links.map(x => x.score)) }, { start: parseHex("0000ED"), end: parseHex("000000") }); return links.map( link => { const first = link.regionA.start < link.regionB.start ? link.regionA : link.regionB; const last = link.regionA.start < link.regionB.start ? link.regionB : link.regionA; const firstS = x(first.start), lastS = x(last.start), firstE = x(first.end); let lastE = x(last.end); if (lastE - firstE < 2) lastE = firstE + 2; const h = Math.floor(cx(-Math.log(link.score))); return { d: `M ${firstS} ${height * 3 / 4} Q ${(firstS + lastE) / 2} 0 ${lastE} ${height * 3 / 4} L ${lastS} ${height * 3 / 4} Q ${(lastS + firstE) / 2} ${height * 0.1} ${firstE} ${height * 3 / 4}`, fill: '#FF' + (h < 0 ? '00' : (h < 15 ? '0' + h.toString(16) : h.toString(16))) + '00' }; }); } export function renderSimpleLinks(links: Link[], x: (value: number) => number, height: number, threshold: number, colorMax: number): Path[] { const crange = { start: threshold, end: Math.max(...links.map(x => x.score), colorMax) }; const p = (h: number): string => h < 0 ? '00' : (h < 15 ? '0' + h.toString(16) : h.toString(16)); const r = linearTransform(crange, { start: parseHex("0000CC"), end: parseHex("0000FF") }); const g = linearTransform(crange, { start: parseHex("0000CC"), end: parseHex("000000") }); const b = linearTransform(crange, { start: parseHex("0000CC"), end: parseHex("000000") }); return links.filter(x => x.score > threshold).sort( (a, b) => a.score - b.score ).map( link => { const first = link.regionA.start < link.regionB.start ? link.regionA : link.regionB; const last = link.regionA.start < link.regionB.start ? link.regionB : link.regionA; const firstC = x((first.start + first.end) / 2), lastC = x((last.start + last.end) / 2); const score = link.score > colorMax ? colorMax : link.score; const rr = Math.floor(r(score)); const gg = Math.floor(g(score)); const bb = Math.floor(b(score)); return { d: `M ${firstC} ${height * 7 / 8} Q ${(firstC + lastC) / 2} 0 ${lastC} ${height * 7 / 8}`, stroke: '#' + p(rr) + p(gg) + p(bb) }; }); }