引言
项目需要在实现一个点击可拓展的用户关系树,框架是Vue
网上找了一下,d3和echarts的Hierarchy Tree实例代码都是一次加载所有用户数据,因为d3的可配置Dom所以选择了d3
d3部分示例代码
const nodeEnter = node.enter().append("g")
.attr("transform", d => `translate(${source.y0},${source.x0})`)
.attr("fill-opacity", 0)
.attr("stroke-opacity", 0)
.on("click", d => {
d.children = d.children ? null : d._children;
update(d);
});
主要修改的就是click函数
d.children存在时要展示节点的数据,否则发送请求在数据源中插入数据并重新渲染树
实现步骤
- d.children存在时用 this.showInfo 控制数据的展示
- 如果不存在,发送数据请求并获取点击的节点在数据源中的索引列表
- 根据索引列表获取点击的节点在数据源中的引用,再插入请求获得的后代用户数据,如果请求到的数据为空则展示该节点的用户数据
- 更新viewBox的宽高,重新渲染树
### 获取节点在数据源中的索引列表 - - - ``` javascript // d代表点击的节点 getIndexList(d) { let indexList = []; let item = ''; // d.depth 节点深度,根节点到该节点的距离 const depth = d.depth; for (let i = 0; i < depth; i++) { // d.y <= d.parent.y ,代表d在父节点的左区,index为0 let index = d.y <= d.parent.y ? 0 : 1; indexList.unshift(index); d = d.parent; } console.log('indexList-----',indexList); return indexList; } ```
获取点击的节点在this.treeData中的引用
insertSourceData(d) {
let indexList = this.getIndexList(d);
let tree = this.treeData;
for (let e = 0; e < indexList.length; e++) {
this.clickItem = tree.children[indexList[e]];
tree = tree.children[indexList[e]];
}
console.log('clickItem-------',this.clickItem);
},
更新viewBox的宽高,重新渲染树
let list = [];
let yList = [];
const root = d3.hierarchy(this.treeData);
// 更新root的后代
root.descendants().forEach((d, i) => {
d.ID = d.data.id;;
list.push(d);
});
this.root = root;
// 更新svg height
let svgHeight = root.height*this.nodeSizeY + 130;
this.height = svgHeight > this.height ? svgHeight : this.height;
// 更新树
this.update(d);
// 更新svg width (x y 反转)
list.forEach(d => {
d.y ? yList.push(d.y): ''
})
let max = Math.max(...yList)
let min = Math.min(...yList)
let width = (max + min >= 0 ? max*2+200 : -min*2+200);
this.width = width > this.width ? width : this.width;