某日接到需求说做个这样的关系图
前期因为用到echart,所以没有考虑别的d3.js来实现,主要是节点的更新,echart2有refresh来实现,但是在echart4已不存在该方法,于是用setOption来重新渲染Tree数据,同层级之间的距离一直不好设置,如果数据节点过大的时候会出现重叠的烦恼。
解决问题1,使用自定义节点图片;
解决问题2,当节点数量过多时,初始化节点全在当前屏幕内;
/***
* 获取初始化节点数据
* this.treeOption.series
* @param arr
* @returns {*}
*/
initOrginalData(arr){
for(let n=0;n<arr.length;n++){
let str = '';
for(let i=0,s;s = arr[n].name[i++];){
str += s;
if(!(i%this.standLength)){
str += '\n';
}
}
arr[n].name = str;
......
}
return arr;
},
/***
* 绘制图谱
* this.treeOption.series
* @param arr
* @returns {*}
*/
initChart(){
let _this = this;
let option = {
tooltip: {
trigger: 'item',
formatter: '{b}:{c}',
hideDelay: 0
},
series: []
};
getData({
"uscCode": localStorage.getItem('selectedUscCode')
}).then(response => {
if (response.code === 200) {
_this.baseSeries[0].children = response.data;
_this.originData = _this.initOrginalData(_this.baseSeries));
_this.myChart = echarts.init(document.getElementById('myChart'));
_this.myChart.setOption(option);
_this.myChart.on('click', this.clickRatio);
_this.adjustTreeView()
}
});
},
/***
* 使得节点初始化均在当前屏幕内
* 更新节点数据
* this.treeOption.series
* @param arr
* @returns {*}
*/
adjustTreeView() {
let zr = this.myChart.getZrender();
let domWidth = zr.painter.getWidth();
let treeWidth = this.getTreeWidth(zr);
if (treeWidth <= domWidth)
return;
var adjustSize = domWidth / treeWidth * 0.95; //多缩小0.05不至于完全充盈dom
var lastNodeX = zr.storage._roots[zr.storage._shapeListOffset - 1].style.x * adjustSize;
var rightOffset = (domWidth - lastNodeX) - (domWidth - treeWidth * adjustSize)/2; //尽可能的让其居中
zr.painter._layers[1].scale = [ adjustSize, adjustSize, 0, 0 ]; //前两个为缩放大小,后两个为缩放原点
zr.painter._layers[1].position = [rightOffset, this.treeTopPadding ]; //偏移量
this.myChart.refresh();
},
getTreeWidth(zr) {
let nodes = zr.storage._roots;
let max = 0;
let min = 0;
for(var i=0; i < nodes.length; i++){
if(nodes[i].type == 'icon' || nodes[i].type == 'p_w_picpath'){
var nodeX = nodes[i].style.x;
if(nodeX > max){
max = nodeX;
continue;
}
if(nodeX < min)
min = nodeX;
}
}
return max - min;
},
/***
* 节点收缩展开
* 更新节点数据
* this.treeOption.series
* @param arr
* @returns {*}
*/
clickRatio(param) {
if(param.data.symbol.indexOf('open1')>0) {
param.data.symbol = param.data.symbol.replace(/open1/g, "close1");
}else if(param.data.symbol.indexOf('close1')>0) {
param.data.symbol = param.data.symbol.replace(/close1/g, "open1");
}
if(!(param.data.children && param.data.children.length > 0)) {
if(param.data.children_bak) {
param.data.children = param.data.children_bak;
this.myChart.refresh();
}else{
this.findById(param.data.id,this.originData);
param.data.children = this.child;
this.myChart.refresh();
}
} else {
param.data.children_bak = param.data.children;
param.data.children = []; //root节点会在refresh时读children的length
this.myChart.refresh();
}
},
/***
* 查找节点
* id, arr
* @param id arr
* @returns {*}
*/
findById(id, arr){
......
}
运行结果如下图所示: