import React, {useState} from 'react'; import {Sankey, ResponsiveContainer} from 'recharts'; import CustomLink from './CustomLink'; import CustomNode from './CustomNode'; import {NoContent, Icon} from 'UI'; interface Node { idd: string; name: string; eventType: string; avgTimeFromPrevious: number | null; } interface Link { id: string; eventType: string; value: number; source: string; target: string; } interface Data { nodes: Node[]; links: Link[]; } interface Props { data: Data; nodeWidth?: number; height?: number; onChartClick?: (filters: any[]) => void; } const SankeyChart: React.FC = ({data, height = 240, onChartClick}: Props) => { const [highlightedLinks, setHighlightedLinks] = useState([]); const [hoveredLinks, setHoveredLinks] = useState([]); function findPreviousLinks(targetNodeIndex: number): Link[] { const previousLinks: Link[] = []; const visitedNodes: Set = new Set(); const findPreviousLinksRecursive = (nodeIndex: number) => { visitedNodes.add(nodeIndex); for (const link of data.links) { if (link.target === nodeIndex && !visitedNodes.has(link.source)) { previousLinks.push(link); findPreviousLinksRecursive(link.source); } } }; findPreviousLinksRecursive(targetNodeIndex); return previousLinks; } const handleLinkMouseEnter = (linkData: any) => { const {payload} = linkData; const link: any = data.links.find(link => link.id === payload.id); const previousLinks: any = findPreviousLinks(link.source).reverse(); previousLinks.push({id: payload.id}); setHoveredLinks(previousLinks.map((link: any) => link.id)); }; const clickHandler = () => { setHighlightedLinks(hoveredLinks); const firstLink = data.links.find(link => link.id === hoveredLinks[0]) || null; const lastLink = data.links.find(link => link.id === hoveredLinks[hoveredLinks.length - 1]) || null; const firstNode = data.nodes[firstLink?.source]; const lastNode = data.nodes[lastLink?.target]; const filters = []; if (firstNode) { filters.push({ operator: 'is', type: firstNode.eventType, value: [firstNode.name], isEvent: true }); } if (lastNode) { filters.push({ operator: 'is', type: lastNode.eventType, value: [lastNode.name], isEvent: true }); } onChartClick?.(filters); }; // const processedData = processData(data); return ( No data available for the selected period. } > } nodePadding={20} sort={true} nodeWidth={4} iterations={128} // linkCurvature={0.9} onClick={clickHandler} link={({source, target, id, ...linkProps}, index) => ( handleLinkMouseEnter(linkProps)} onMouseLeave={() => setHoveredLinks([])} /> )} margin={{right: 130, bottom: 50}} > ); }; export default SankeyChart;