scene-case/default/performance-diagnosis-flowchart

Example page

import { BugOutlined } from '@ant-design/icons';
import { ExtensionCategory, Graph, HoverActivate, idOf, register } from '@antv/g6';
import { ReactNode } from '@antv/g6-extension-react';
import { Flex, Typography } from 'antd';
import { useEffect, useRef } from 'react';
import { createRoot } from 'react-dom/client';

const { Text } = Typography;

const ACTIVE_COLOR = '#f6c523';
const COLOR_MAP = {
  'pre-inspection': '#3fc1c9',
  problem: '#8983f3',
  inspection: '#f48db4',
  solution: '#ffaa64',
};

class HoverElement extends HoverActivate {
  getActiveIds(event) {
    const { model, graph } = this.context;
    const { targetType, target } = event;
    const targetId = target.id;

    const ids = [targetId];
    if (targetType === 'edge') {
      const edge = model.getEdgeDatum(targetId);
      ids.push(edge.source, edge.target);
    } else if (targetType === 'node') {
      ids.push(...model.getRelatedEdgesData(targetId).map(idOf));
    }

    graph.frontElement(ids);

    return ids;
  }
}

register(ExtensionCategory.NODE, 'react', ReactNode);
register(ExtensionCategory.BEHAVIOR, 'hover-element', HoverElement);

const Node = ({ data }) => {
  const { text, type } = data.data;

  const isHovered = data.states?.includes('active');
  const isSelected = data.states?.includes('selected');
  const color = isHovered ? ACTIVE_COLOR : COLOR_MAP[type];

  const containerStyle = {
    width: '100%',
    height: '100%',
    background: color,
    border: `3px solid ${color}`,
    borderRadius: 16,
    cursor: 'pointer',
  };

  if (isSelected) {
    Object.assign(containerStyle, { border: `3px solid #000` });
  }

  return (
    <Flex style={containerStyle} align="center" justify="center">
      <Flex vertical style={{ padding: "8px 16px", textAlign: "center" }} align="center" justify="center">
        {type === 'problem' && <BugOutlined style={{ color: "#fff", fontSize: 24, marginBottom: 8 }} />}
        <Text style={{ color: "#fff", fontWeight: 600, fontSize: 16 }}>{text}</Text>
      </Flex>
    </Flex>
  );
};

export const PerformanceDiagnosisFlowchart = () => {
  const containerRef = useRef();

  useEffect(() => {
    fetch('https://assets.antv.antgroup.com/g6/performance-diagnosis.json')
      .then((res) => res.json())
      .then((data) => {
        const graph = new Graph({
          container: containerRef.current,
          data,
          autoFit: 'view',
          node: {
            type: 'react',
            style: (d) => {
              const style = {
                component: <Node data={d} />,
                ports: [{ placement: 'top' }, { placement: 'bottom' }],
              };

              const size = {
                'pre-inspection': [240, 120],
                problem: [200, 120],
                inspection: [330, 100],
                solution: [200, 120],
              }[d.data.type] || [200, 80];

              Object.assign(style, {
                size,
                dx: -size[0] / 2,
                dy: -size[1] / 2,
              });
              return style;
            },
            state: {
              active: {
                halo: false,
              },
              selected: {
                halo: false,
              },
            },
          },
          edge: {
            type: 'polyline',
            style: {
              lineWidth: 3,
              radius: 20,
              stroke: '#8b9baf',
              endArrow: true,
              labelText: (d) => d.data.text,
              labelFill: '#8b9baf',
              labelFontWeight: 600,
              labelBackground: true,
              labelBackgroundFill: '#f8f8f8',
              labelBackgroundOpacity: 1,
              labelBackgroundLineWidth: 3,
              labelBackgroundStroke: '#8b9baf',
              labelPadding: [1, 10],
              labelBackgroundRadius: 4,
              router: {
                type: 'orth',
              },
            },
            state: {
              active: {
                stroke: ACTIVE_COLOR,
                labelBackgroundStroke: ACTIVE_COLOR,
                halo: false,
              },
            },
          },
          layout: {
            type: 'antv-dagre',
          },
          behaviors: ['zoom-canvas', 'drag-canvas', 'hover-element', 'click-select'],
        });

        graph.render();
      });
  }, []);

  return <div style={{ width: "100%", height: "100%" }} ref={containerRef}></div>;
};

const root = createRoot(document.getElementById('container'));
root.render(<PerformanceDiagnosisFlowchart />);