import React, { useCallback, useMemo } from 'react' import { observer } from 'mobx-react' import type { LinearMafDisplayModel } from '../../stateModel' import type { NodeWithIdsAndLength } from '../../types' import type { HierarchyNode } from 'd3-hierarchy' const hitboxStyle = { pointerEvents: 'all', cursor: 'pointer', strokeWidth: 8, stroke: 'transparent', } as const const Tree = observer(function ({ model }: { model: LinearMafDisplayModel }) { const { // rowHeight is needed for redrawing after zoom change // eslint-disable-next-line @typescript-eslint/no-unused-vars rowHeight: _rowHeight, treeAreaWidth, hierarchy, showBranchLen, nodeDescendantNames, } = model const clearHighlight = useCallback(() => { model.setHighlightedRowNames(undefined) }, [model]) const nodeHandlers = useMemo(() => { const handlers = new Map< HierarchyNode, { onMouseEnter: () => void onClick: (event: React.MouseEvent) => void } >() if (hierarchy) { for (const node of hierarchy.descendants()) { const names = nodeDescendantNames.get(node) handlers.set(node, { onMouseEnter: () => { model.setHighlightedRowNames(names, { x: node.x!, y: node.y!, }) }, onClick: (event: React.MouseEvent) => { event.preventDefault() if (names && names.length > 0) { model.setTreeMenuAnchor({ x: event.clientX, y: event.clientY, names, }) } }, }) } } return handlers }, [model, hierarchy, nodeDescendantNames, treeAreaWidth]) return ( <> {hierarchy ? [...hierarchy.links()].map(link => { const { source, target } = link const sy = source.x! const ty = target.x! // @ts-expect-error const tx = showBranchLen ? target.len : target.y // @ts-expect-error const sx = showBranchLen ? source.len : source.y const sourceHandlers = nodeHandlers.get(source) const targetHandlers = nodeHandlers.get(target) return ( {/* Visible lines */} {/* Invisible hitbox lines */} ) }) : null} ) }) export default Tree