import React, { useMemo, useRef, useEffect, useCallback } from 'react'; import { v1 as uuidv1 } from 'uuid'; import { SquishRect } from './types'; import { xtransform } from '../../../utils/coordinates'; import { ClipPath } from '../../clippath'; import { renderSquishBigBedData } from './utils'; import TooltipContent from './tooltip'; import { Domain } from '../../../utils/types'; import { Rect } from '../motif/types'; import { useTooltip } from '../../../hooks/useTooltip'; export type SquishBigBedProps = { data?: Rect[]; width: number; rowHeight: number; id?: string; transform?: string; color?: string; domain: Domain; svgRef?: React.RefObject; onClick?: (item: Rect) => void; onMouseOver?: (item: Rect) => void; onMouseOut?: () => void; onHeightChanged?: (height: number) => void; tooltipContent?: React.FC; }; /** * Represents a BigBed track rendered in squish mode as at UCSC. A squished BigBed renders genomic regions * of interest (such as peaks) as narrow rectangles packed into an optimal number of rows so overlapping regions * are distinguishable from one another. */ const SquishBigBed: React.FC = props => { const [ mouseOver, mouseOut ] = useTooltip(props.tooltipContent || TooltipContent, props.width, props.svgRef); const uuid = useRef(uuidv1()); const x = useCallback(xtransform(props.domain, props.width), [ props ]); const color = props.color || "#000000"; const rendered: SquishRect[][] = useMemo( () => renderSquishBigBedData(props.data || [], x), [ props.data, props.domain, props.width ] ); const height = props.rowHeight * rendered.length; const id = props.id || uuid.current.toString(); useEffect( () => { props.onHeightChanged && props.onHeightChanged(height); }, [ rendered, props.rowHeight, props.onHeightChanged ]); return ( { rendered.map( (group, i) => ( {group.map( (rect, j) => ( props.onClick && props.onClick(rect)} onMouseOut={() => { props.onMouseOut && props.onMouseOut(); mouseOut(); }} onMouseOver={(e: React.MouseEvent) => { e.persist(); props.onMouseOver && props.onMouseOver(rect); mouseOver(e, rect); }} /> ))} ))} ); } export default SquishBigBed;