import { BamRect } from './types'; import { groupFeatures } from '../../../utils/coordinates'; import { Domain } from './../../../utils/types'; /** * Renders dense Bam data to SVG rectangles; overlapping regions are merged into single rectangles. * @param data input data vector. * @param x a transform function for mapping data coordinates to SVG coordinates. */ export function renderDenseBamData(data: BamRect[], x: (value: number) => number): BamRect[] { const results: BamRect[] = []; data.sort( (a, b) => a.start - b.start ).forEach( (current, i) => { if ((i === 0 || current.start > data[i - 1].end || current.color != data[i - 1].color) ) results.push({ start: x(current.start) < 0 ? 0 : x(current.start), end: x(current.end), color: current.color, cigarOps: current.cigarOps, strand: current.strand, seq: current.seq }); else results[results.length - 1].end = x(current.end); return results; }); return results; } export function renderSquishBamData(data: BamRect[], x: (value: number) => number, domain: Domain ): BamRect[][] { return groupFeatures( data.sort( (a, b) => a.start - b.start ).map( x => ({ coordinates: { start: x.start, end: x.end }, color: x.color, name: "", cigarOps: x.cigarOps, strand: x.strand, seq: x.seq }) ), x, 0 ).map( group => ( group.map( feature => ({ start: x(feature.coordinates.start) < 0 ? 0 : x(feature.coordinates.start), end: x(feature.coordinates.end), color: feature.color, cigarOps: feature.cigarOps.map(cg=> { return { opStart: x(cg.opStart) < 0 ? 0: x(cg.opStart) ,opEnd: x(cg.opEnd), op: cg.op }}), strand: feature.strand, seq: x(feature.coordinates.start) < 0 ? feature.seq?.slice(domain.start-feature.coordinates.start,feature.seq.length) : feature.seq })) )); }