目录
引入tree图
引入echarts图,需要指定容器有明确的宽高。
根据官方文档,需要先定义一个<div>节点,并使用CSS使得该节点具有宽度和高度。,初始化的时候,传入该节点,图标的大小默认即为该节点的大小,除非声明了opts.width或opts.height将其覆盖。(引自官网:Handbook - Apache ECharts)。
<template>
<div id="chart-panel" :class="className" :style="{ height: newHeight, width: width }" />
</template>
问题1:高度固定时,当节点数据过多,导致重叠,为解决该问题,本例高度根据数据动态计算,数据由父组件传入。
使用watch监听父组件传入的数据,发生变化时更新图,本例中,数据发生变化时,高度必然会发生变化,因此不需要在高度变化时重复更新视图。
当高度发生变化时,调用echartsInstance.resize方法改变图表的大小
watch: {
chartData: {
handler(val) {
this.$nextTick(() => this.updateChart(val));
},
deep: true,
},
height(newVal, oldVal) {
if (newVal != oldVal) {
this.newHeight = newVal;
}
},
},
updateChart(chartData) {
// 获取dom节点
var container = document.getElementById("chart-panel");
// dom节点高度为最新获取的高度
container.style.height = this.newHeight;
// 改变图表大小
this.chart.resize();
this.chart.setOption({
series: [
{
data: [chartData],
},
],
});
},
问题2:本例中非叶子节点的值显示在左边,当内容过长会被遮挡,因此使用formatter将内容格式化处理,超过指定长度时省略或换行。
label: {
//每个节点所对应的标签的样式
position: "left",
verticalAlign: "middle",
align: "right",
fontSize: 16,
formatter(v) {
let text = v.name;
if (text.length > 20) {
return (text = `${text.slice(0, 19)}...`);
// return (text = `${text.slice(0, 18)}\n${text.slice(20)}`);
}
},
},
完整代码:
<template>
<div id="chart-panel" :class="className" :style="{ height: newHeight, width: width }" />
</template>
<script>
import echarts from "echarts";
// require("echarts/theme/macarons"); // echarts theme
// require("echarts/lib/component/tooltip");
// require("echarts/lib/chart/tree");
import resize from "../../dashboard/mixins/resize";
const data = {
children: [
{
children: [
{
name: "操作系统:windows",
},
{
name: "组件:mysql",
},
{
name: "端口:https",
},
{
name: "设备名称:mysql",
},
],
name: "资产指纹",
},
],
name: "zyt-test0045",
};
export default {
name: "AssetFingerprint",
mixins: [resize],
props: {
className: {
type: String,
default: "chart",
},
width: {
type: String,
default: "100%",
},
height: {
type: String,
default: "200px",
},
assetId: String,
ip: String,
chartData: Object,
},
data() {
return {
chart: null,
// chartData: this.chartData,
queryParams: {
assetId: this.assetId,
ip: this.ip,
},
newHeight: this.height,
};
},
watch: {
chartData: {
handler(val) {
this.$nextTick(() => this.updateChart(val));
},
deep: true,
},
height(newVal, oldVal) {
if (newVal != oldVal) {
this.newHeight = newVal;
}
},
},
mounted() {
},
created() {
this.$nextTick(() => {
this.initChart();
});
},
beforeDestroy() {
if (!this.chart) {
return;
}
this.chart.dispose();
this.chart = null;
},
methods: {
updateChart(chartData) {
var container = document.getElementById("chart-panel");
container.style.height = this.newHeight;
this.chart.resize();
this.chart.setOption({
series: [
{
data: [chartData],
},
],
});
},
initChart() {
this.chart = echarts.init(this.$el, "macarons");
this.chart.setOption({
tooltip: {
//提示框组件
trigger: "item",
triggerOn: "mousemove",
show: true,
},
label: {},
series: [
{
type: "tree",
data: [],
top: "1%",
left: "20%",
bottom: "1%",
right: "30%",
symbolSize: 9, //标记的大小,就是那个小圆圈,默认7
label: {
//每个节点所对应的标签的样式
position: "left",
verticalAlign: "middle",
align: "right",
fontSize: 16,
formatter(v) {
let text = v.name;
if (text.length > 20) {
return (text = `${text.slice(0, 19)}...`);
// return (text = `${text.slice(0, 18)}\n${text.slice(20)}`);
}
},
},
leaves: {
label: {
//叶子节点的特殊配置,叶子节点和非叶子节点的标签位置不同
position: "right",
verticalAlign: "middle",
align: "left",
},
},
emphasis: {
focus: "series",
},
itemStyle: {
normal: {
borderColor: "#1890FF",
lineStyle: {
color: "#D9D9D9 ",
},
},
},
expandAndCollapse: true, //子树折叠和展开的交互,默认打开
animationDuration: 550, //初始动画的时长,支持回调函数,默认1000
animationDurationUpdate: 750, //数据更新动画的时长,默认300
},
],
});
},
},
};
</script>