antV G6
需求:根据后端返回的值,画出当前配货单关联的单据,根据单号跳转,显示每条单据中商品数量
实现效果:
![](https://img.haomeiwen.com/i7755932/4f98cec61a19186b.png)
基本元素
node
node是一个流程图的一个节点
一个node节点
{
id: '001',
x: 300,
y: 300,
label: '一个说明',
shape: 'nodeName'
}
- id:这个属性用于同边进行关联
- x,y:节点的位置(由于节点的位置变化非常频繁,所以直接在外层实现,不需要在定义节点时设置 )
- color:节点的颜色
- shape:确定节点的类型,如果不填写,默认为 circle
- size: 节点的大小,可以是数组,对 size 的解析,由节点的开发者确定
- label: 节点上的文本
- style: 节点图形的样式
- 用户自定义属性......
注册node节点
G6.registerNode(name, arguments, extend);
参数:
- name:节点名称(node中shape的值)
- arguments:节点参数
- extend:继承节点名称
edge
边是连接两个节点,比如id = 0的节点,和id = 1的节点,连接的边:
{ id: '0-1', source: '0', target: '1' }
注册边
G6.registerEdge(name, arguments, extend)
antV G6常见的数据格式:
const data = {
nodes: [
{ id: '0', label: '起始' },
{ id: '1', label: '步骤一' },
{ id: '2', label: '步骤二' },
{ id: '2.1', label: '分步骤一' },
{ id: '2.2', label: '分步骤二' },
],
edges: [
{ id: '0-1', source: '0', target: '1' },
{ id: '1-2', source: '1', target: '2' },
{ id: '2-2.1', source: '2', target: '2.1' },
{ id: '2-2.2', source: '2', target: '2.2' },
],
};
处理数据
json格式解析下:
![](https://img.haomeiwen.com/i7755932/ab1c5e779d9a9d7c.png)
将后端返回的数据,处理成需要的格式:
// 初始化节点数据
const nodes = [
{
id: '0',
label: '销售订单',
shape: 'node',
size: 100,
code: escOrderId,
pk: orderPk,
type: 'order',
},
];
// 初始划边数据
const edges = [];
// 字符串转json
const parseData = JSON.parse(data);
// 处理数据
const nodeList = this.getNodeList(parseData, 1, false);
// 根据getNodeList函数处理的结果,生成node,edges相关数据
nodeList.map((item) => {
nodes.push({
id: item.id,
label: item.label,
shape: 'node',
code: item.code,
type: item.type,
pk: item.pk,
});
edges.push({ ...item.curredge });
return nodeList;
});
const drawData = { nodes, edges };
// 绘制流程图函数
this.drawRangeMapCharts(drawData);
处理数据函数getNodeList
参数:
data:未处理的数据,
cur:当前节点,
flag: 是否子节点
返回数据格式:
return {
id:'',
lable:'',
curredge:{},// 当前节点相关的边
}
getNodeList = (data, curr, flag) => {
const nodes = data.map((item, index) => {
let currNode;
let childrenNode = [];
if (flag) { // 子节点
currNode = {
id: `${curr}.${index + 1}`,
label: `${item.type}--${item.quantity ? item.quantity : ''}`,
code: item.code,
type: item.type,
pk: item.pk,
curredge: {
id: `${curr}-${curr}.${index + 1}`,
source: `${curr}`,
target: `${curr}.${index + 1}`,
},
};
} else {
currNode = {
id: `${index + 1}`,
label: `${item.type}`,
code: item.code,
type: item.type,
pk: item.pk,
curredge: {
id: `0-${index + 1}`,
source: '0',
target: `${index + 1}`,
},
};
}
// nodeArr.push(currNode);
if (item.children) {
childrenNode = this.getNodeList(item.children, currNode.id, true);
childrenNode.unshift(currNode);
}
return childrenNode.length ? childrenNode : currNode;
});
const arr = [].concat(...nodes);
return arr;
}
绘制图形
引入相关依赖
import G6 from '@antv/g6';
import Plugins from '@antv/g6-plugins';
搭建容器
const net = new G6.Net({ // net网图
id: 'bmountNode', // 容器id
height: this.props.height,
fitView: 'tc', //自适应视口方向
plugins: [dagre], // 插件
});
插件:
const dagre = new G6.Plugins['layout.dagre']({
rankdir: 'LR', // 布局方向,根节点在左,往右布局
nodesep: 100, // 节点距离
ranksep: 100, // 层次距离
});
注册node
G6.registerNode('node', {
cssSize: true, // 不使用内部 size 作为节点尺寸
getHtml: function getHtml(cfg) {
const { model } = cfg;
const dom = Util.createDOM(`<div class="${style.node}">
${model.label}
<div class="${style.link}">${model.code ? model.code : ''}</div>
</div>`);
return dom;
},
}, 'html');
edge
net.edge().shape('arrow');// 定义箭头形状
点击事件
点击单据号跳转
net.on('click', (ev) => {
const { item } = ev;
if (item) {
const target = item._attrs;
const { model } = target;
// model.code 单据号
// mode.type 单据类型
}
});
可能出现的问题:被canvas图层覆盖,无法获取点击的节点,需要调整图层的z-index值
最后,存入数据,渲染
net.source(nodes, edges);// 存入数据
net.render();
网友评论