前言
需求: echarts树形图6级, 总共300个节点, 默认展开3级
嗯嗯, 以为很简单, 直接上数据渲染就完了, 全部展开后, 结果页面密密麻麻的重叠; 搜索全网,竟然没有很好的解决方式, 连echarts社区都没有更好的解决方案, what? 研究了一天, 必需解决它
配置参数 ? 度 ?
把 type: 'tree' 的一百多个配置参数仔仔细细看了一遍, 也尝试了, 然而并没有卵用.
那就度一下吧, 找到几篇博客都是拿到所有节点, 把每一个节点的lineHeight * 节点数去计算高度, 设置echarts总高度; 那就按照网上的方法试一下吧, 结果是默认高度6000. 我才展开3级,都没触底,高度就6000了???
认真捋一下思路
- 拿到所有节点;
- 筛选出2级以上的并且展开的节点;
- 计算筛选后的节点总高度, 每次展开隐藏节点时重新计算
- 设置echarts高度
先看对比结果
再上代码
<template>
<div class="app-container">
<div class="chart-tree">
<div id="chart-box" ref="chart-box"></div>
</div>
<div class="chart-right">右侧占位</div>
</div>
</template>
<script setup>
import * as echarts from "echarts";
const { proxy } = getCurrentInstance();
const seriesSource = ref([]);
const chartTree = ref(null);
onMounted(() => {
chartTree.value = echarts.init(proxy.$refs["chart-box"]);
setItemStyle(seriesSource.value);
setChart();
});
// 处理数据样式
function setItemStyle(data = []) {
data.forEach(item => {
let obj = {};
// 标签样式
item.label = {};
obj.lineHeight = 24;
obj.borderRadius = 4;
obj.borderWidth = 1;
obj.padding = [0, 5];
obj.position = "left";
if (item.level == 2) {
obj.color = "#fff";
obj.borderColor = "#1338f4";
obj.backgroundColor = "#1338f4";
} else {
obj.color = "#000";
obj.borderColor = "#1338f4";
obj.backgroundColor = "#fff";
}
item.label = obj;
if (item.children && item.children.length) {
setItemStyle(item.children);
}
});
}
function setChart() {
let option = {
tooltip: {
trigger: "item",
triggerOn: "mousemove",
formatter: function(params) {
let str = "";
params.treeAncestors.forEach((item, index) => {
if (index > 0 && index < params.treeAncestors.length - 1) {
str += item.name + " > ";
}
if (index == params.treeAncestors.length - 1) {
str += item.name;
}
});
return str;
}
},
series: [
{
type: "tree",
data: seriesSource.value,
top: "1%",
left: "7%",
bottom: "1%",
right: "20%",
symbolSize: 7,
lineStyle: {
color: "#1338f4"
},
roam: true,
label: {
formatter: function(params) {
let tempName = "";
if (params.data.children && params.data.children.length) {
tempName = `${params.data.name} (${params.data.children.length}个节点)`;
} else {
tempName = `${params.data.name}`;
}
if (params.collapsed && params.treeAncestors.length > 2) {
return tempName;
} else {
return `${params.data.name}`;
}
}
},
leaves: {
label: {
position: "right",
verticalAlign: "middle",
align: "left"
}
},
initialTreeDepth: 2, // 展开层级, null 表示全展开
expandAndCollapse: true
}
]
};
chartTree.value.setOption(option);
maxHeight();
chartTree.value.on("click", params => {
maxHeight();
});
}
function maxHeight() {
let expandNode = 0;
let allNodes = chartTree.value._chartsViews[0]._data.tree._nodes;
for (let index = 0; index < allNodes.length; index++) {
const element = allNodes[index];
if (element.depth > 1 && element.isExpand && element.parentNode.isExpand) {
expandNode += element.children.length;
}
}
let expandNodeHeight = 30 * expandNode;
let currentHeight = Math.max(796, expandNodeHeight);
setTimeout(() => {
chartTree.value.resize({ height: currentHeight });
}, 300);
}
</script>
<style lang="scss" scoped>
.app-container {
.chart-tree {
flex: 1;
overflow: hidden;
#chart-box {
width: 100%;
height: 100%;
transition: all 0.3s;
}
}
.chart-right {
width: 600px;
overflow: hidden;
}
}
</style>
结束语
不想细说了, 千言万语都在代码里, 虽然代码量不大,但是真真的一天没说话的搞事情