参考:
官网:@antv/g6
官网:React中使用@antv/g6
官网:使用dom自定义节点
⚠️ 注意: G6 的节点/边事件不支持 DOM 类型的图形。如果需要为 DOM 节点绑定事件,请使用原生 DOM 事件。例如:
官网:React中自定义节点
直接上代码
1、自定义边
const flowLine = {
draw(cfg: any, group: any) {
const startPoint = cfg.startPoint;
const endPoint = cfg.endPoint;
const sourceModel = cfg?.sourceNode?._cfg?.model;
const targetModel = cfg?.targetNode?._cfg?.model;
const path = [
['M', startPoint.x, startPoint.y - 20],
['L', startPoint.x, (startPoint.y + endPoint.y) / 2 + 8],
['L', endPoint.x, (startPoint.y + endPoint.y) / 2 + 8],
['L', endPoint.x, endPoint.y],
];
const sourceSelected = sourceModel?.isAbnormal;
const targetSelected = targetModel?.isAbnormal;
const isSelected = !!sourceModel?.parentMetricNodeId
? targetSelected && sourceSelected
: targetSelected;
const shape = group.addShape('path', {
attrs: {
stroke: isSelected ? 'red' : '#cacaca',
path,
},
});
return shape;
},
}
2、自定义node
import React from 'react';
import { Rect, Text, Group } from '@antv/g6-react-node';
import { nullIf, toFixed, toPercentage } from '@/utils/tools';
interface Props {
cfg: any;
}
export default function ParentChild({ cfg }: Props) {
const { name, value, cycleValueDiff = 0, onClick } = cfg;
return (
<Group draggable>
<Rect
style={{
width: 180,
height: 'auto',
fill: '#fff',
shadowColor: '#ddd',
shadowBlur: 4,
radius: [4],
justifyContent: 'center',
}}
>
<Rect style={{ fill: '#FBEAEA' }}>
<Text
style={{
fill: '#000',
margin: [6, 12, 8, 14],
fontSize: 14,
fontWeight: 'bold',
}}
>
{nullIf(name)}
</Text>
<Text style={{ fill: '#1890FF', fontSize: 18, margin: [0, 12, 6, 14] }}>
{nullIf(value ? parseFloat(value) : null, { render: toFixed })}
</Text>
</Rect>
<Rect
style={{
padding: [5, 0],
width: 'auto',
margin: [8, 14, 6, 14],
flexDirection: 'row',
}}
onClick={onClick}
>
<Text style={{ fill: '#5F5F5F', fontSize: 14 }} onClick={onClick}>{`环比:`}</Text>
<Text
style={{ fill: '#E66060', fontSize: 14 }}
onClick={onClick}
>
{nullIf(cycleValueDiff, { render: toPercentage })?.toString()}
</Text>
</Rect>
</Rect>
</Group>
);
}
3、在组件里边使用
const graphRef = useRef<any>();
useEffect(() => {
G6.registerNode('node-child', createNodeFromReact(<ParentChild />));
G6.registerEdge('flow-line', flowLine);
const container: any = document.getElementById('container');
const width = container.scrollWidth;
const height = container.scrollHeight || window.innerHeight;
const cfg = getTreeGraphCofig({ width, height });
const graph = new G6.TreeGraph(cfg);
graphRef.current = graph;
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);
};
}, []);
//加载渲染数据
const graph = graphRef.current;
getIndicatorsTree(defaultParams).then((res) => {
if (res?.data?.length > 0) {
graph.data(res?.data?.[0]);
graph.setMaxZoom(1);
graph.render();
graph.fitView([8, 16], { onlyOutOfViewPort: true, ratioRule: 'min' });
// 添加事件
appenAutoShapeListener(graph);
}
});