import { ElementDatum, Graph, IElementEvent } from '@antv/g6'; import isEmpty from 'lodash/isEmpty'; import { useCallback, useEffect, useMemo, useRef } from 'react'; import { buildNodesAndCombos } from './util'; import styles from './index.less'; const TooltipColorMap = { combo: 'red', node: 'black', edge: 'blue', }; interface IProps { data: any; show: boolean; } const ForceGraph = ({ data, show }: IProps) => { const containerRef = useRef(null); const graphRef = useRef(null); const nextData = useMemo(() => { if (!isEmpty(data)) { const graphData = data; const mi = buildNodesAndCombos(graphData.nodes); return { edges: graphData.edges, ...mi }; } return { nodes: [], edges: [] }; }, [data]); const render = useCallback(() => { const graph = new Graph({ container: containerRef.current!, autoFit: 'view', autoResize: true, behaviors: [ 'drag-element', 'drag-canvas', 'zoom-canvas', 'collapse-expand', { type: 'hover-activate', degree: 1, // 👈🏻 Activate relations. }, ], plugins: [ { type: 'tooltip', enterable: true, getContent: (e: IElementEvent, items: ElementDatum) => { if (Array.isArray(items)) { if (items.some((x) => x?.isCombo)) { return `

${items?.[0]?.data?.label}

`; } let result = ``; items.forEach((item) => { result += `

${item?.id}

`; if (item?.entity_type) { result += `
Entity type: ${item?.entity_type}
`; } if (item?.weight) { result += `
Weight: ${item?.weight}
`; } if (item?.description) { result += `

${item?.description}

`; } }); return result + '
'; } return undefined; }, }, ], layout: { type: 'combo-combined', preventOverlap: true, comboPadding: 1, spacing: 100, }, node: { style: { size: 150, labelText: (d) => d.id, // labelPadding: 30, labelFontSize: 40, // labelOffsetX: 20, labelOffsetY: 20, labelPlacement: 'center', labelWordWrap: true, }, palette: { type: 'group', field: (d) => { return d?.entity_type as string; }, }, }, edge: { style: (model) => { const weight: number = Number(model?.weight) || 2; const lineWeight = weight * 4; return { stroke: '#99ADD1', lineWidth: lineWeight > 10 ? 10 : lineWeight, }; }, }, }); if (graphRef.current) { graphRef.current.destroy(); } graphRef.current = graph; graph.setData(nextData); graph.render(); }, [nextData]); useEffect(() => { if (!isEmpty(data)) { render(); } }, [data, render]); return (
); }; export default ForceGraph;