import React, { useReducer, Reducer, useEffect, useCallback } from 'react'; import { GenomeBrowserAction, ToolTipData, ContextMenuData } from './types'; import SelectRegion from './selectregion' import { Domain } from '../../utils/types'; import StackedTracks from './stackedtracks'; import Tooltip from "../tooltip/tooltip"; import { TooltipContext } from "../tooltip/tooltipcontext"; import ContextMenu, { ContextMenuContext } from './../contextmenu/contextmenu'; import BrowserContextMenu from './contextmenu'; export type GenomeBrowserProps = { domain: Domain; innerWidth: number; width: number | string; dragRegionHeight?: number; svgRef?: React.RefObject; onModeChange?: (id: string, displayMode: string) => void onDomainChanged?: (domain: Domain) => void; noMargin?: boolean; children?: React.ReactNode; }; export type GenomeBrowserState = { domain: Domain; width: number; height: number; tooltip: ToolTipData; contextmenu: ContextMenuData; }; function reducer(previousState: GenomeBrowserState, action: GenomeBrowserAction): GenomeBrowserState { switch (action.type) { case "domainChanged": return { ...previousState, domain: action.newDomain }; case "heightChanged": return { ...previousState, height: action.newHeight }; case "tooltipChanged": return { ...previousState, tooltip: action.tooltip }; case "contextMenuChanged": return { ...previousState, contextmenu: action.contextmenu }; } } /** * Provides a genome browser container which wraps children in an SVG * element and provides a mechanism for dragging to select regions. */ const GenomeBrowser: React.FC = props => { const [ state, dispatch ] = useReducer>( reducer, { domain: props.domain, height: 0, width: props.innerWidth, tooltip: { show: false, x: 0, y: 0, width: 0, height: 0, content: undefined }, contextmenu: { show: false, x: 0, y: 0, id: '', displayMode: undefined, displayModeOptions: undefined } } ); useEffect(() => { dispatch({ type: "domainChanged", newDomain: props.domain }); }, [ props.domain ]); const setTooltip = useCallback((tooltip: ToolTipData) => { dispatch({ type: "tooltipChanged", tooltip}); }, [ dispatch ]); const setContextMenu = useCallback((contextmenu: ContextMenuData) => { dispatch({ type: "contextMenuChanged", contextmenu}); }, [ dispatch ]); return ( props.onDomainChanged && props.onDomainChanged(domain) } /> dispatch({ type: "heightChanged", newHeight: height + 150 }) } id="root" svgRef={props.svgRef} > {props.children}
{state.tooltip.content}
); }; export default GenomeBrowser;