React + antvX6流程图

MyComponent
import React from 'react';
import styles from './index.less';
export default class MyComponenAdd extends React.Component {
  shouldComponentUpdate() {
    const node = this.props.node;
    if (node) {
      if (node.hasChanged('data')) {
        return true;
      }
    }
    return false;
  }
  handleClick = () => {
    this.props.getType(this.props.node.store.data.type);
  };
  render() {
    const { node } = this.props;
    return (
      <div
        className={styles.box}
        dangerouslySetInnerHTML={{ __html: node.store.data.label }}
        onClick={this.handleClick}
      />
    );
  }
} 
publicStyle
let publicStyle = {
  shape: 'my-rect',
  lineShape: 'edge',
  positionList: [
    {
      x: 0,
      y: 140,
    },
    {
      x: 250,
      y: 140,
    },
    {
      x: 500,
      y: 140,
    },
    {
      x: 750,
      y: 140,
    },
    {
      x: 250,
      y: 280,
    },
  ],
  attrs: {
    body: {
      rx: 6,
      ry: 6,
    },
  },
  lineAttrs: {
    line: {
      stroke: '#a30014',
      targetMarker: {
        // name: 'block',
        width: 12,
        height: 8,
      },
    },
  },
  ports: {
    groups: {
      top: {
        position: 'top',
        attrs: {
          circle: {
            r: 4,
            magnet: true,
            stroke: '#5F95FF',
            strokeWidth: 1,
            fill: '#fff',
            style: {
              visibility: 'hidden',
            },
          },
        },
      },
      right: {
        position: 'right',
        attrs: {
          circle: {
            r: 4,
            magnet: true,
            stroke: '#5F95FF',
            strokeWidth: 1,
            fill: '#fff',
            style: {
              visibility: 'hidden',
            },
          },
        },
      },
      bottom: {
        position: 'bottom',
        attrs: {
          circle: {
            r: 4,
            magnet: true,
            stroke: '#5F95FF',
            strokeWidth: 1,
            fill: '#fff',
            style: {
              visibility: 'hidden',
            },
          },
        },
      },
      left: {
        position: 'left',
        attrs: {
          circle: {
            r: 4,
            magnet: true,
            stroke: '#5F95FF',
            strokeWidth: 1,
            fill: '#fff',
            style: {
              visibility: 'hidden',
            },
          },
        },
      },
    },
    items: [
      {
        group: 'top',
        id: '125c00ca-08dd-44f1-b22f-06c06e43ecb5',
      },
      {
        group: 'right',
        id: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
      },
      {
        group: 'bottom',
        id: '69b15387-d6f4-43e7-8282-40fe5ad78505',
      },
      {
        group: 'left',
        id: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
      },
    ],
  },
  labelList: [
    `<div style="line-height:70px">工单A</div>`,
    `<div style="line-height:33px">工单B<br/><a href="#">B</a></div>`,
    `<div style="line-height:33px">工单C<a href="#">C</a></div> `,
    `<div style="line-height:33px"><a href="#">工单D</a><br/><div>`,
    `<div style="line-height:33px">工单E<br/><a href="#">运营E</a></div>`,
  ],
};
export default publicStyle;
index
import React, { useEffect } from 'react';
import { Graph, Shape } from '@antv/x6'; // graph.getNodes() // 获取画布中所有的点
import '@antv/x6-react-shape';
import insertCss from 'insert-css';
import publicStyle from './publicStyle';
import MyComponent from './MyComponent';

let graph = null; // 画布
export default function AntvDemo() {
  useEffect(() => {
    preWork();
    graph = new Graph({
      container: document.getElementById('container_antdx6'),
      grid: false, // 是否显示画布网格
      panning: false, // 禁用画布拖动
      interacting: {
        nodeMovable: false,
      },
      mousewheel: {
        enabled: false, // 鼠标滚轮缩放禁用
      },
      connecting: {
        router: {
          name: 'manhattan',
          args: {
            padding: 1,
          },
        },
        connector: {
          name: 'rounded',
          args: {
            radius: 8,
          },
        },
        anchor: 'center',
        connectionPoint: 'anchor',
        allowBlank: false,
        snap: {
          radius: 20,
        },
        createEdge() {
          return new Shape.Edge({
            attrs: {
              line: {
                stroke: '#808080',
                strokeWidth: 2,
                targetMarker: {
                  name: 'block',
                  width: 12,
                  height: 8,
                },
              },
            },
            zIndex: 0,
          });
        },
        validateConnection({ targetMagnet }) {
          return !!targetMagnet;
        },
      },
    });
    Graph.registerNode(
      'my-rect',
      {
        inherit: 'react-shape',
        x: 200,
        y: 150,
        width: 180,
        height: 70,
        attrs: {
          body: {
            stroke: '#000', // 边框颜色
            fill: '#fff', // 背景颜色
            rx: 10,
            ry: 10,
          },
          label: {
            fill: '#000', // 文字颜色
            fontSize: 12, // 文字大小
          },
        },
        component: <MyComponent getType={getType} />,
      },
      true,
    );
    // 反序列化
    graph.fromJSON([
      {
        shape: publicStyle.lineShape,
        attrs: { ...publicStyle.lineAttrs },
        id: '8734eb26-5641-435b-b5b2-d926709406fc',
        zIndex: 0,
        source: {
          cell: 'a14fb6b4-5213-466d-aee9-4b2bc17e3e6a',
          port: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
        },
        target: {
          cell: 'efe4bd07-7d6e-4ab0-88f4-7df69a0769a3',
          port: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
        },
      },
      {
        shape: publicStyle.lineShape,
        attrs: { ...publicStyle.lineAttrs },
        id: '151d4994-c04a-4dea-8c94-f5b08f035b1e',
        zIndex: 0,
        source: {
          cell: 'a14fb6b4-5213-466d-aee9-4b2bc17e3e6a',
          port: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
        },
        target: {
          cell: '94c5b26d-585f-49cf-a531-c51786a61eda',
          port: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
        },
      },
      {
        shape: publicStyle.lineShape,
        attrs: { ...publicStyle.lineAttrs },
        id: '9c850d5c-369d-4e02-90ad-1210f6b67a59',
        zIndex: 0,
        source: {
          cell: 'efe4bd07-7d6e-4ab0-88f4-7df69a0769a3',
          port: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
        },
        target: {
          cell: '32cbc0e8-36a2-41c7-b24d-5b59c0928d81',
          port: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
        },
      },
      {
        shape: publicStyle.lineShape,
        attrs: { ...publicStyle.lineAttrs },
        id: 'e6d8b145-c7e2-49df-952f-563a9ea43df4',
        zIndex: 0,
        source: {
          cell: '94c5b26d-585f-49cf-a531-c51786a61eda',
          port: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
        },
        target: {
          cell: '32cbc0e8-36a2-41c7-b24d-5b59c0928d81',
          port: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
        },
      },
      {
        shape: publicStyle.lineShape,
        attrs: { ...publicStyle.lineAttrs },
        id: '9e392cd2-7113-49c2-95c9-925321bc80ad',
        zIndex: 0,
        source: {
          cell: '32cbc0e8-36a2-41c7-b24d-5b59c0928d81',
          port: '89561f1c-5eef-457d-8d8a-3e6e853a0020',
        },
        target: {
          cell: '9763d660-d0ff-4663-b00d-d5c4d057d0f9',
          port: 'fa4d6acb-9c41-4c5c-92f1-8751295b23c7',
        },
      },
      {
        shape: publicStyle.shape,
        label: publicStyle.labelList[0],
        position: { ...publicStyle.positionList[0] },
        attrs: { ...publicStyle.attrs },
        ports: { ...publicStyle.ports },
        type: '0',
        id: 'a14fb6b4-5213-466d-aee9-4b2bc17e3e6a',
        zIndex: 1,
      },
      {
        shape: publicStyle.shape,
        label: publicStyle.labelList[1],
        position: { ...publicStyle.positionList[1] },
        attrs: { ...publicStyle.attrs },
        ports: { ...publicStyle.ports },
        type: '1',
        id: 'efe4bd07-7d6e-4ab0-88f4-7df69a0769a3',
        zIndex: 2,
      },
      {
        shape: publicStyle.shape,
        label: publicStyle.labelList[2],
        position: { ...publicStyle.positionList[2] },
        attrs: { ...publicStyle.attrs },
        ports: { ...publicStyle.ports },
        type: '2',
        id: '32cbc0e8-36a2-41c7-b24d-5b59c0928d81',
        zIndex: 3,
      },
      {
        shape: publicStyle.shape,
        label: publicStyle.labelList[3],
        position: { ...publicStyle.positionList[3] },
        attrs: { ...publicStyle.attrs },
        ports: { ...publicStyle.ports },
        type: '3',
        id: '9763d660-d0ff-4663-b00d-d5c4d057d0f9',
        zIndex: 4,
      },
      {
        shape: publicStyle.shape,
        label: publicStyle.labelList[4],
        position: { ...publicStyle.positionList[4] },
        attrs: { ...publicStyle.attrs },
        ports: { ...publicStyle.ports },
        type: '4',
        id: '94c5b26d-585f-49cf-a531-c51786a61eda',
        zIndex: 5,
      },
    ]);
  }, []);

  // 获取type
  const getType = (type) => {
    console.log('🚀 ~ file: index.jsx:771 ~ getType ~ type', type);
  };
  // 初始化graph的css
  const preWork = () => {
    const container = document.getElementById('content_wrap');
    const graphContainer = document.createElement('div');
    graphContainer.id = 'container_antdx6';
    container.appendChild(graphContainer);
    insertCss(`
        #container {
          height:100%;
          display: flex;
          border: 1px solid #dfe3e8;
        }
        #container_antdx6 {
          width: 100%;
          height: 100%;
        }
     
        .x6-widget-transform {
          margin: -1px 0 0 -1px;
          padding: 0px;
          border: 1px solid #239edd;
        }
        .x6-widget-transform > div {
          border: 1px solid #239edd;
        }
        .x6-widget-transform > div:hover {
          background-color: #3dafe4;
        }
        .x6-widget-transform-active-handle {
          background-color: #3dafe4;
        }
        .x6-widget-transform-resize {
          border-radius: 0;
        }
        .x6-widget-selection-inner {
          border: 1px solid #239edd;
        }
        .x6-widget-selection-box {
          opacity: 0;
        }
      `);
  };
  return (
    <div style={{ height: '400px' }}>
      <div id="content_wrap" style={{ height: '400px' }}></div>
    </div>
  );
}
版本
  • @antv/x6:^1.34.5
  • @antv/x6-react-shape:^1.6.3
注意事项
  • 如果报错 insertCss npm i insert-css -S
  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值