// import { useEffect, useState } from 'react'; import { makeStyles, Theme } from '@material-ui/core'; import { useEffect } from 'react'; const getStyles = makeStyles((theme: Theme) => ({ container: { borderTopLeftRadius: '8px', borderBottomLeftRadius: '8px', overflow: 'auto', backgroundColor: 'white', // height: 'auto', // width: '100%', }, rootNode: { transition: 'all .25s', cursor: 'pointer', transformOrigin: '50% 50%', transformBox: 'fill-box', '& circle': { transition: 'all .25s', }, '& text': { transition: 'all .25s', }, '&:hover, &:focus': { transform: 'scale(1.1)', filter: 'drop-shadow(3px 3px 5px rgba(0, 0, 0, .2))', }, '&:focus': { outline: 'none', '& circle': { fill: '#06AFF2', stroke: '#06AFF2', }, '& text': { fill: 'white', } } }, childNode: { transition: 'all .25s', cursor: 'pointer', transformOrigin: '50% 50%', transformBox: 'fill-box', '& circle': { transition: 'all .25s', }, '& text': { transition: 'all .25s', }, '&:hover, &:focus': { transform: 'scale(1.1)', filter: 'drop-shadow(3px 3px 5px rgba(0, 0, 0, .2))', }, '&:focus': { outline: 'none', '& svg path': { fill: 'white', }, '& circle': { fill: '#06AFF2', stroke: '#06AFF2', }, '& text': { fill: 'white', } } }, subChild: { transition: 'all .25s', cursor: 'pointer', outline: 'none', '& circle': { transition: 'all .25s', }, '& rect': { transition: 'all .25s', }, '&:hover, &:focus': { transform: 'scale(1.05)', transformOrigin: 'center', filter: 'drop-shadow(3px 3px 5px rgba(0, 0, 0, .2))', "& rect": { opacity: 0, }, "& .selected": { opacity: 1, transform: 'translate(-40px, -77px) scale(3)', }, }, } })); const capitalize = (s: string) => { return s.charAt(0).toUpperCase() + s.slice(1); } const Topo = (props: any) => { const classes = getStyles(); const { nodes, setNode, setCord } = props; useEffect(() => { const center = document.getElementById('center'); if ((center as HTMLElement).dispatchEvent) { (center as HTMLElement).dispatchEvent(new MouseEvent('click', { bubbles: true, cancelable: true, view: window, })); (center as HTMLElement).focus(); } }, [nodes.length]); const WIDTH = 800; // width for svg const HEIGHT = 600; // height for svg const LINE1 = 160; // line lenght from lv1 node const LINE2 = 270; // line lenght from lv2 node const ANGLE2 = 10; // angle offset for lv2 node const R1 = 68; // root node radius const R2 = 45; // lv1 node radius const R3 = 30; // lv2 node radius const LIMIT = 10; // limit to show lv1 node const BOUNDARY_ANGLE = 45; // boundary angle let steps = 0; // angle step to avoid graph out of boundary let centerNode: any; return (
{nodes.map((node: any, index: number) => { if (node?.infos?.type === 'RootCoord') { centerNode = node; return null; } const connectedLength = node?.connected.length; if (index < LIMIT) { let angle = 270 / nodes.length * index + BOUNDARY_ANGLE * steps; if (((90 - BOUNDARY_ANGLE / 2) < angle && angle < (90 + BOUNDARY_ANGLE / 2)) || ((270 - BOUNDARY_ANGLE / 2) < angle && angle < (270 + BOUNDARY_ANGLE / 2))) { steps++; angle = angle + BOUNDARY_ANGLE; } const nodeCenterX = WIDTH / 2 + LINE1 * Math.cos(angle * Math.PI / 180); const nodeCenterY = HEIGHT / 2 + LINE1 * Math.sin(angle * Math.PI / 180); let childAngle = angle; if ((angle > BOUNDARY_ANGLE && angle < 90) || (angle > (180 + BOUNDARY_ANGLE) && angle < 270)) { childAngle = angle - ANGLE2; } if ((angle > 270 && angle < (270 + BOUNDARY_ANGLE)) || (angle > 90 && angle < (90 + BOUNDARY_ANGLE))) { childAngle = angle + ANGLE2; } const childNodeCenterX = WIDTH / 2 + LINE2 * Math.cos(childAngle * Math.PI / 180); const childNodeCenterY = HEIGHT / 2 + LINE2 * Math.sin(childAngle * Math.PI / 180); let icon; switch (node?.infos?.type) { case 'DataCoord': icon = ; break; case 'IndexCoord': icon = ; break; case 'QueryCoord': icon = ( ); break; default: icon = ( ); break; } return ( {connectedLength && ()} { setNode(node); }} > {icon && {icon}} {capitalize(node?.infos?.name)} {connectedLength && ( <> { setCord(node) }}> {`${connectedLength} Node(s)`} )} ); } return null; })} { setNode(centerNode); }} > Milvus
); }; export default Topo;