前言
在第一节实现了, 根据准备好的数据生成树形图,根据数据数值改变节点以及节点文本颜色。
本节实现功能:
1、叶子节点点击事件:点击叶子节点,弹出弹框展示叶子节点信息
2、加载时默认展开/收缩节点
3、展开/收缩节点后,画布适应视口
4、更新展示数据后,需要销毁画布以更新树图
实现效果如下:
树图结构:
效果一:
效果二:
初加载仅展开三层数据
效果三:
点击第三层数据的时候视图缩小适应窗口,虽然这个效果有点突然
最近G6好像更新了文档,更新后又要重新翻翻找找啃文档了我太难了 点击文档菜单的时候有些文档点不开,应该是还在完善中。
数据准备
在第一节的数据处理上更进一步的处理。在节点数据中绑定要展示的数据,在各个节点上加入。
// 整理树形数据
changeTreeData() {
this.treedata = [];
this.getTreedata.forEach((item, i) => {
let data2 = [];
for (var i in item.childrenList) {
let data3 = [];
for (var j in item.childrenList[i].childrenList) {
let data4 = [];
for (var v in item.childrenList[i].childrenList[j].childrenList) {
let msg = item.childrenList[i].childrenList[j].childrenList[v];
data4.push({
id: ...,
label: ...,
status:...,
//叶子节点!! 绑定要显示的数据 msg
msg: msg,
isFather:...,
});
}
data3.push({
id: ...,
label:...,
children: data4,
isFather: ...,
status: ...,
});
}
data2.push({
id: ...,
label:...,
children: data3,
isFather: ...,
status: ...,
});
}
this.treedata.push({
label:...,
children: data2,
isFather: ...,
status: ...,
});
});
//生成树图的方法
this.showChart();
},
叶子节点的点击事件
- 本例做的是点击第四级数据打开窗口,打印node可以看到其实我们可以在节点点击事件中获得很多节点的信息,可以根据需要自主做判断
graph.on("node:click", (ev) => {
const node = ev.item;
if (node._cfg.model.depth == 3) {
//这是一个根据叶子节点数据id查询节点详情的方法
this.getValueDetailById(node._cfg.model.msg.Id);
//打开弹窗
this.dialogVisible = true;
}
});
默认展开/收缩节点
官方文档:https://antv-g6.gitee.io/zh/docs/manual/middle/states/defaultBehavior/#collapse-expand
- 同样,根据数据中的isFather判断,这块的判断可以根据需要灵活变化
// 只适用于树图,展开或收起子树
// isFather标识是否默认展开 ture展开
G6.Util.traverseTree(data, function (item) {
if (!item.isFather) {
//collapsed为true时默认收起
item.collapsed = true;
}
});
展开/收缩适应视口
官方文档:https://g6.antv.vision/zh/docs/api/graphFunc/transform#graphfitviewpadding
- 我做的这个适应效果原理是在每次点击节点时让画布内容适应视口,但是效果有点突然,我觉得应该有更好更舒适的解决方案,但是目前还没有找到。
// 跟css写法一样 20,10分别为top bottom,left right的间距值
graph.fitView(20,10);
- 写在节点点击事件中
graph.on("node:click", (ev) => {
const node = ev.item;
graph.fitView(20,10);
if (node._cfg.model.depth == 3) {
//这是一个根据叶子节点数据id查询节点详情的方法
this.getValueDetailById(node._cfg.model.msg.Id);
//打开弹窗
this.dialogVisible = true;
}
});
销毁画布
- 声明一个变量:
export default {
name: "eCharts",
data() {
return {
contorlGraph: "",
}
}
}
- 在生成图方法中指向树图
showChart() {
...
const graph = new G6.TreeGraph({
...
this.contorlGraph = graph;
...
})
}
在使用的方法中
changeDate() {
//销毁画布
this.contorlGraph.destroy();
//树图数据置空
this.getTreedata = [];
//获取数据方法
this.getAllTreeData();
},
生成图代码
showChart() {
const data = this.treedata[0];
const container = document.getElementById("container");
const minimap = new G6.Minimap({
size: [150, 100],
});
if (container) {
const width = container.clientWidth;
const height = container.clientHeight;
const graph = new G6.TreeGraph({
// 图的 DOM 容器,可以传入该 DOM 的 id 或者直接传入容器的 HTML 节点对象。
container: container,
width: width,
height: height,
// 设置画布的模式 包含default 模式和 edit 模式
modes: {
// default 模式中包含点击选中节点行为和拖拽画布行为
default: [
{
type: 'collapse-expand',
trigger: 'click',
},
// 拖拽画布 和 缩放画布
"drag-canvas",
"zoom-canvas",
],
},
fitView:true,
fitViewPadding: [ 20, 40, 50, 20 ],
// 默认的节点设置
defaultNode: {
//节点的大小
size: 14,
// 指定边连入节点的连接点的位置
anchorPoints: [
[0, 0.5],
[1, 0.5],
],
// 节点样式
style: {
fill: "#C6E5FF",
stroke: "#5B8FF9",
},
},
// 默认的配置
defaultEdge: {
type: "cubic-horizontal",
style: {
stroke: "#A3B1BF",
},
},
plugins: [minimap],
layout: {
type: "compactBox",
direction: "LR",
// 指定节点 ID
getId: function getId(d) {
return d.id;
},
// 指定节点高度
getHeight: function getHeight() {
return 16;
},
//指定节点宽度
getWidth: function getWidth() {
return 16;
},
// 指定节点之间的垂直间距
getVGap: function getVGap() {
return 10;
},
// 指定节点之间的水平间距
getHGap: function getHGap() {
return 100;
},
},
});
// 为不同节点进行不同的配置 必须在 render 之前调用
graph.node(function (node) {
return {
style: {
fill:
node.depth == 3 || node.depth == 2
? node.status
? "#6b9bfa"
: "#c1422b"
: "#6b9bfa",
stroke:
node.depth == 3 || node.depth == 2
? node.status
? "#6b9bfa"
: "#c1422b"
: "#6b9bfa",
},
//String 类型。标签文本的文字内容
label: node.label,
labelCfg: {
// 文本的偏移
offset: 10,
// 文本相对于节点的位置
position:
node.children && node.children.length > 0 ? "left" : "right",
//文本样式
style: {
fill:
node.depth == 3 || node.depth == 2
? node.status
? "#2c3e50"
: "#c1422b"
: "#2c3e50",
},
},
};
});
graph.on("node:click", (ev) => {
const node = ev.item;
graph.fitView(20,10);
if (node._cfg.model.depth == 3) {
//这是一个根据叶子节点数据id查询节点详情的方法
this.getValueDetailById(node._cfg.model.msg.Id);
//打开弹窗
this.dialogVisible = true;
}
});
// isFather标识是否默认展开 ture展开
G6.Util.traverseTree(data, function (item) {
if (!item.isFather) {
item.collapsed = true;
}
});
this.contorlGraph = graph;
//初始化数据
graph.data(data);
//渲染视图
graph.render();
graph.fitView();
}
},
——————————————————————————————————————
以上是我的一些学习记录,大多都是啃文档来的,如果有理解错误或者理解不周全的地方欢迎指正~