MiniTopology.tsx 2.9 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586
  1. import { FC } from 'react';
  2. import { makeStyles, Theme } from '@material-ui/core';
  3. import { MiniTopoProps } from './Types';
  4. const getStyles = makeStyles((theme: Theme) => ({
  5. container: {
  6. height: '100%',
  7. width: 'auto',
  8. },
  9. childNode: {
  10. transition: 'all .25s',
  11. cursor: 'pointer',
  12. transformOrigin: '50% 50%',
  13. transformBox: 'fill-box',
  14. '& circle': {
  15. transition: 'all .25s',
  16. },
  17. '& text': {
  18. transition: 'all .25s',
  19. },
  20. '&:hover, &:focus': {
  21. transform: 'scale(1.1)',
  22. filter: 'drop-shadow(3px 3px 5px rgba(0, 0, 0, .2))',
  23. },
  24. '&:focus': {
  25. outline: 'none',
  26. '& svg path': {
  27. fill: 'white',
  28. },
  29. '& circle': {
  30. fill: '#06AFF2',
  31. stroke: '#06AFF2',
  32. },
  33. '& text': {
  34. fill: 'white',
  35. }
  36. }
  37. },
  38. }));
  39. const capitalize = (s: string) => {
  40. return s.charAt(0).toUpperCase() + s.slice(1);
  41. }
  42. const MiniTopo: FC<MiniTopoProps> = (props) => {
  43. const classes = getStyles();
  44. const { selectedCord, selectedChildNode, setCord } = props;
  45. const WIDTH = 400; // width for svg
  46. const HEIGHT = 400; // height for svg
  47. const LINE = 80; // line lenght from lv2 node
  48. const ANGLE = 10; // angle offset for lv2 node
  49. const R1 = 45; // root node radius
  50. const R2 = 30; // lv1 node radius
  51. const W3 = 20; // width of child rect
  52. const childNodeCenterX = WIDTH / 2 + LINE * Math.cos(ANGLE * Math.PI / 180);
  53. const childNodeCenterY = HEIGHT / 2 + LINE * Math.sin(ANGLE * Math.PI / 180);
  54. return (
  55. <svg className={classes.container} width={WIDTH} height={HEIGHT} viewBox={`0 0 ${WIDTH} ${HEIGHT}`} xmlns="http://www.w3.org/2000/svg">
  56. <rect width="100%" height="100%" fill="white" />
  57. <line x1={`${WIDTH / 3}`} y1={`${HEIGHT / 3}`} x2={childNodeCenterX} y2={childNodeCenterY} stroke="#06AFF2" />
  58. <g className={classes.childNode} onClick={() => { setCord(null) }}>
  59. <circle cx={`${WIDTH / 3}`} cy={`${HEIGHT / 3}`} r={R1} fill="white" stroke="#06AFF2" />
  60. <text fontFamily="Roboto" alignmentBaseline="middle" textAnchor="middle" fill="#06AFF2" fontWeight="700" fontSize="12" x={`${WIDTH / 3}`} y={`${HEIGHT / 3}`}>{selectedCord ? capitalize(selectedCord.infos?.name) : ''}</text>
  61. </g>
  62. <g>
  63. <svg width="60" height="60" viewBox="0 0 60 60" x={childNodeCenterX - 30} y={childNodeCenterY - 30}>
  64. <circle cx={R2} cy={R2} r={R2} fill="#06AFF2" stroke="white" />
  65. <rect className="selected" x={R2 - W3 / 2} y={R2 - W3 / 2} width={W3} height={W3} fill="white" />
  66. </svg>
  67. <text fontFamily="Roboto" textAnchor="middle" fill="#82838E" fontSize="12" x={childNodeCenterX} y={childNodeCenterY + 50}>{`${selectedChildNode ? selectedChildNode.infos?.name : ''}`}</text>
  68. </g>
  69. </svg >
  70. );
  71. };
  72. export default MiniTopo;