12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091 |
- import React, { FC, useCallback, useEffect, useRef } from 'react';
- import { GraphEdge, GraphNode } from './utils';
- interface OwnProps {
- nodes: GraphNode[];
- edges: GraphEdge[];
- direction?: 'UD' | 'DU' | 'LR' | 'RL';
- onDoubleClick?: (node: string) => void;
- width?: string;
- height?: string;
- }
- interface ConnectedProps {}
- interface DispatchProps {}
- export type Props = OwnProps & ConnectedProps & DispatchProps;
- export const NetworkGraph: FC<Props> = ({ nodes, edges, direction, width, height, onDoubleClick }) => {
- const network = useRef<any>(null);
- const ref = useRef(null);
- const onNodeDoubleClick = useCallback(
- (params: { nodes: string[] }) => {
- if (onDoubleClick) {
- onDoubleClick(params.nodes[0]);
- }
- },
- [onDoubleClick]
- );
- useEffect(() => {
- const createNetwork = async () => {
- // @ts-ignore no types yet for visjs-network
- const visJs = await import(/* webpackChunkName: "visjs-network" */ 'visjs-network');
- const data = {
- nodes: toVisNetworkNodes(visJs, nodes),
- edges: toVisNetworkEdges(visJs, edges),
- };
- const options = {
- width: '100%',
- height: '100%',
- autoResize: true,
- layout: {
- improvedLayout: true,
- hierarchical: {
- enabled: true,
- direction: direction ?? 'DU',
- sortMethod: 'directed',
- },
- },
- interaction: {
- navigationButtons: true,
- dragNodes: false,
- },
- };
- network.current = new visJs.Network(ref.current, data, options);
- network.current?.on('doubleClick', onNodeDoubleClick);
- };
- createNetwork();
- return () => {
- // unsubscribe event handlers
- if (network.current) {
- network.current.off('doubleClick');
- }
- };
- }, [direction, edges, nodes, onNodeDoubleClick]);
- return (
- <div>
- <div ref={ref} style={{ width: width ?? '100%', height: height ?? '60vh' }} />
- </div>
- );
- };
- function toVisNetworkNodes(visJs: any, nodes: GraphNode[]): any[] {
- const nodesWithStyle: any[] = nodes.map((node) => ({
- ...node,
- shape: 'box',
- }));
- return new visJs.DataSet(nodesWithStyle);
- }
- function toVisNetworkEdges(visJs: any, edges: GraphEdge[]): any[] {
- const edgesWithStyle: any[] = edges.map((edge) => ({ ...edge, arrows: 'to', dashes: true }));
- return new visJs.DataSet(edgesWithStyle);
- }
|