| | |
| | | import React, { useState } from 'react' |
| | | import { XFlow, XFlowCanvas } from '@antv/xflow' |
| | | /** 图的各种扩展交互组件 */ |
| | | import { CanvasMiniMap, CanvasScaleToolbar, CanvasSnapline } from '@antv/xflow' |
| | | /** 图的配置项 */ |
| | | import { useGraphConfig } from './config-graph' |
| | | import { message } from 'antd' |
| | | import React, { useEffect, useState } from 'react'; |
| | | import ReactDOM from 'react-dom'; |
| | | import { data } from './data'; |
| | | import G6 from '@antv/g6'; |
| | | import "./index.css" |
| | | |
| | | import './index.css' |
| | | export default function() { |
| | | const ref = React.useRef(null); |
| | | let graph = null; |
| | | |
| | | const Demo = () => { |
| | | /** 画布配置 */ |
| | | const graphConfig = useGraphConfig() |
| | | |
| | | /** 画布渲染数据 */ |
| | | const [graphData, setGraphData] = useState() |
| | | |
| | | /** XFlow初始化完成的回调 */ |
| | | const onLoad = async app => { |
| | | const node = [ |
| | | { id: 'root1', width: 150, height: 40, renderKey: 'NODE1', info: { text: 'root1' } }, |
| | | { id: 'down1', width: 150, height: 40, renderKey: 'NODE2', info: { text: 'down1' } }, |
| | | { id: 'down2', width: 150, height: 40, renderKey: 'NODE2', info: { text: 'down2' } }, |
| | | { id: 'down3', width: 150, height: 40, renderKey: 'NODE2', info: { text: 'down3' } }, |
| | | ] |
| | | const edges = [ |
| | | { |
| | | id: 'root1-down1', |
| | | source: 'root1', |
| | | target: 'down1', |
| | | renderKey: 'EDGE1', |
| | | edgeContentWidth: 60, |
| | | edgeContentHeight: 30, |
| | | info: { line: 'root1-down1' }, |
| | | useEffect(() => { |
| | | if (!graph) { |
| | | graph = new G6.Graph({ |
| | | container: ReactDOM.findDOMNode(ref.current), |
| | | width: document.documentElement.clientWidth, |
| | | height: document.documentElement.clientHeight, |
| | | modes: { |
| | | default: [ |
| | | 'drag-canvas', |
| | | 'zoom-canvas', |
| | | 'drag-node', |
| | | ], |
| | | edit: ['click-select'] |
| | | }, |
| | | layout: { |
| | | type: 'dagre', |
| | | direction: 'LR', |
| | | }, |
| | | defaultNode: { |
| | | shape: 'node', |
| | | type: 'rect', |
| | | labelCfg: { |
| | | style: { |
| | | fill: '#000000A6', |
| | | fontSize: 14, |
| | | }, |
| | | { |
| | | id: 'root1-down2', |
| | | source: 'root1', |
| | | target: 'down2', |
| | | renderKey: 'EDGE2', |
| | | edgeContentWidth: 60, |
| | | edgeContentHeight: 30, |
| | | info: { line: 'root1-down2' }, |
| | | }, |
| | | { |
| | | id: 'root1-down3', |
| | | source: 'root1', |
| | | target: 'down3', |
| | | label: '1:N(纯文本)', |
| | | info: { line: 'root1-down3' }, |
| | | }, |
| | | ] |
| | | const newGraphData = { nodes, edges } |
| | | setGraphData(newGraphData) |
| | | |
| | | const graph = await app.getGraphInstance() |
| | | graph.on('node:click', ({ node }) => { |
| | | const nodeData = node.getData() |
| | | message.success(`${nodeData.id}节点被点击了`) |
| | | }) |
| | | graph.on('edge:click', ({ edge }) => { |
| | | edge.toFront() |
| | | const edgeData = edge.getData() |
| | | message.success(`${edgeData.id}连线被点击了`) |
| | | }) |
| | | }, |
| | | style: { |
| | | // 仅在 keyShape 上生效 |
| | | fill: 'lightblue', |
| | | stroke: '#888', |
| | | lineWidth: 1, |
| | | radius: 7, |
| | | }, |
| | | linkPoints: { |
| | | top: true, |
| | | bottom: true, |
| | | left: true, |
| | | right: true, |
| | | // ... 四个圆的样式可以在这里指定 |
| | | }, |
| | | }, |
| | | defaultEdge: { |
| | | shape: 'polyline', |
| | | }, |
| | | nodeStateStyles: { |
| | | // 各状态下的样式,平铺的配置项仅在 keyShape 上生效。需要在其他 shape 样式上响应状态变化则写法不同,参见上文提到的 配置状态样式 链接 |
| | | hover: { |
| | | fillOpacity: 0.1, |
| | | lineWidth: 1, |
| | | }, |
| | | }, |
| | | }); |
| | | } |
| | | graph.data(data); |
| | | graph.render(); |
| | | |
| | | // 监听鼠标进入节点事件 |
| | | graph.on('node:mouseenter', (evt) => { |
| | | const node = evt.item; |
| | | // 激活该节点的 hover 状态 |
| | | graph.setItemState(node, 'hover', true); |
| | | }); |
| | | |
| | | return ( |
| | | <XFlow |
| | | className="xflow-user-container" |
| | | graphData={graphData} |
| | | graphLayout={{ |
| | | layoutType: 'dagre', |
| | | layoutOptions: { |
| | | type: 'dagre', |
| | | rankdir: 'TB', |
| | | nodesep: 60, |
| | | ranksep: 40, |
| | | }, |
| | | }} |
| | | onLoad={onLoad} |
| | | isAutoCenter={true} |
| | | > |
| | | <XFlowCanvas config={graphConfig}> |
| | | <CanvasScaleToolbar position={{ top: 12, left: 12 }} /> |
| | | <CanvasMiniMap |
| | | miniMapClz="xflow-custom-minimap" |
| | | nodeFillColor="#ccc" |
| | | minimapOptions={{ |
| | | width: 200, |
| | | height: 120, |
| | | }} |
| | | position={{ top: 12, right: 12 }} |
| | | /> |
| | | <CanvasSnapline color="#1890ff" /> |
| | | </XFlowCanvas> |
| | | </XFlow> |
| | | ) |
| | | } |
| | | // 监听鼠标离开节点事件 |
| | | graph.on('node:mouseleave', (evt) => { |
| | | const node = evt.item; |
| | | // 关闭该节点的 hover 状态 |
| | | graph.setItemState(node, 'hover', false); |
| | | }); |
| | | |
| | | export default Demo |
| | | graph.on('node:click', (evt) => { |
| | | const node = evt.item; |
| | | const model = node.getModel(); |
| | | // 在这里打开模态框或者编辑表格,传入model以便用于初始化编辑内容 |
| | | showModal(model); |
| | | }); |
| | | }, []); |
| | | |
| | | return <div ref={ref}></div>; |
| | | } |