SOURCE

console 命令行工具 X clear

                    
>
console
G6.registerNode(
  'tree-node',
  {
    drawShape: function drawShape(cfg, group) {
      const rect = group.addShape('rect', {
        attrs: {
          fill: '#fff',
          stroke: 'green',
          x: 0,
          y: 0,
          width:1,
          height: 1
        },
        name: 'rect-shape',
      });
      const content = cfg.name.replace(/(.{19})/g, '$1\n');
      const text = group.addShape('text', {
        attrs: {
          text: content,
          x: 0,
          y: 0,
          textAlign: 'left',
          textBaseline: 'middle',
          fill: 'red',
        },
        name: 'text-shape',
      });
      const bbox = text.getBBox();
      const hasChildren = cfg.children && cfg.children.length > 0;
      rect.attr({
        x: -bbox.width / 2 - 4,
        y: -bbox.height / 2 - 6,
        width: bbox.width + (hasChildren ? 26 : 12),
        height: bbox.height + 12,
      });
      text.attr({
        x: -bbox.width / 2,
        y: 0
      })
      if (hasChildren) {
        group.addShape('text', {
          attrs: {
            x: bbox.width / 2 + 14,
            y: bbox.height / 2,
            r: 6,
            // symbol: cfg.collapsed ? G6.Marker.expand : G6.Marker.collapse,
            stroke: 'blue',
            lineWidth: 2,
            text: cfg.desc.replace(/\D/g, ''),
          },
          name: 'collapse-icon',
        });
      }
      return rect;
    },
    update: (cfg, item) => {
      const group = item.getContainer();
      const icon = group.find((e) => e.get('name') === 'collapse-icon');
      icon.attr('symbol', cfg.collapsed ? G6.Marker.expand : G6.Marker.collapse);
    },
  },
  'single-node',
);

const getPathInfo = (cfg) => {
  const startPoint = cfg.startPoint;
  const endPoint = cfg.endPoint;
  const { x: startX, y: startY } = startPoint;
  const { x: endX, y: endY } = endPoint;
  const Ydiff = endY - startY;
  const slope = Ydiff !== 0 ? Math.min(500 / Math.abs(Ydiff), 20) : 0;
  const cpOffset = slope > 15 ? 0 : 16;
  const offset = Ydiff < 0 ? cpOffset : -cpOffset;

  const line1EndPoint = {
    x: startX + slope,
    y: endY + offset,
  };
  const line2StartPoint = {
    x: line1EndPoint.x + cpOffset,
    y: endY,
  };

  // 控制点坐标
  const controlPoint = {
    x: ((line1EndPoint.x - startX) * (endY - startY)) / (line1EndPoint.y - startY) + startX,
    y: endY,
  };

  let path = [
    ['M', startX, startY],
    ['L', line1EndPoint.x, line1EndPoint.y],
    ['Q', controlPoint.x, controlPoint.y, line2StartPoint.x, line2StartPoint.y],
    ['L', endX, endY],
  ];

  if (Math.abs(Ydiff) <= 5) {
    path = [
      ['M', startX, startY],
      ['L', endX, endY],
    ];
  }
  const { startArrow, endArrow } = cfg;


  return {
    startArrow,
    endArrow,
    path,
    line2StartPoint,
    endY,
  };
};

G6.registerEdge(
    'fund-line',
    {
      // @ts-ignore
      draw: function draw(cfg = {}, group) {
        debugger
        const { style: edgeStyle, label: labelCfg } = cfg;

        const { startArrow, endArrow, path, line2StartPoint, endY } = getPathInfo(cfg);
        const { style: labelStyle } = labelCfg || {};
        const line = group && group.addShape('path', {
          attrs: {
            path,
            stroke: '#ccc',
            startArrow,
            endArrow,
            ...(typeof edgeStyle === 'function' ? edgeStyle(cfg, group) : edgeStyle),
          },
          name: 'path-shape',
        })
        return line;
      },
    },
  );

const container = document.getElementById('container');
const width = container.scrollWidth;
const height = container.scrollHeight || 500;
const graph = new G6.TreeGraph({
  container: 'container',
  width,
  height,
  modes: {
    default: [
      {
        type: 'collapse-expand',
        onChange: function onChange(item, collapsed) {
          const data = item.get('model');
          graph.updateItem(item, {
            collapsed,
          });
          data.collapsed = collapsed;
          return true;
        },
      },
      'drag-canvas',
      'zoom-canvas',
    ],
  },
  defaultNode: {
    type: 'tree-node',
    anchorPoints: [
      [0, 0.5],
      [1, 0.5],
    ],
  },
  defaultEdge: {
    // type: 'cubic-horizontal',
    type: 'fund-line',
    style: {
      stroke: 'green',
      endArrow: {
        path: G6.Arrow.vee(20, 20, 10), // 自定义箭头路径
        d: 16, // 偏移量
        fill: 'red',
        stroke: 'red'
      }
    },
  },
  edgeCfg: {
    type: 'fund-line',
    edgeStateStyles: {
        hover: {
            stroke: '#1890ff',
            lineWidth: 2,
        },
    },
    style: {
      stroke: '#40a9ff',
    },
    endArrow: {
      fill: '#40a9ff',
    },
  },
  layout: {
    type: 'compactBox',
    direction: 'LR',
    getId: function getId(d) {
      return d.id;
    },
    getHeight: function getHeight() {
      return 16;
    },
    getWidth: function getWidth() {
      return 16;
    },
    getVGap: function getVGap() {
      return 20;
    },
    getHGap: function getHGap() {
      return 120;
    },
  },
});
fetch('https://gw.alipayobjects.com/os/antvdemo/assets/data/modeling-methods.json')
  .then((res) => res.json())
  .then((data) => {
    G6.Util.traverseTree(data, function (item) {
      item.id = item.name;
      item.desc = item.name + 1
    });
    graph.data(data);
    graph.render();
    graph.fitView();
  });

if (typeof window !== 'undefined')
  window.onresize = () => {
    if (!graph || graph.get('destroyed')) return;
    if (!container || !container.scrollWidth || !container.scrollHeight) return;
    graph.changeSize(container.scrollWidth, container.scrollHeight);
  };
<div id="container"></div>

本项目引用的自定义外部资源