vue3中动态设置echarts图的高度
近期写个vue3项目,中间要使用echarts图,因为要适配不同的显示器,简直快被搞疯了。这个问题搞了无数次,但每次都会遇到,记录一下本次的解决方案
一、组件中的写法
组件中只需要把html标签写出来就行了,然后加JavaScript代码
<el-card class="top-graph" ref="topGra">
<div style="height: 100%;" ref="speed"></div>
</el-card>
样式我就不写了,外层是个elementplus中的el-card,内层是要渲染的速度曲线图
js中相关的代码:
import { ref, reactive, onMounted, watch, nextTick } from 'vue'
import { useElementSize } from '@vueuse/core' // 使用vueuse获取dom元素的尺寸
// 点击表格中的眼睛图标时,改变右侧顶部的数据,需要一个索引
const dataIndex = ref(0)
onMounted(() => {
nextTick(() => {
drawChart(dataIndex.value, speed.value)
})
})
import { drawChart } from './components/LineChartOptions'
const speed = ref(null)
const topGra = ref(null)
const { width, height } = useElementSize(topGra)
console.log(width.value, height)
watch(() => [dataIndex, height], (newVal, oldVal) => {
console.log(newVal)
// currentHeight.value = newVal
drawChart(newVal[0].value, speed.value, newVal[1].value)
}, { deep: true })
这里有点复杂的逻辑,echarts图是变化的,需要根据dataIndex这个响应式数据来切换加载的数据源,同时,要自适应显示图的高度
实现的逻辑:监听dataIndex, height这两个值的变化情况,发生变化时,重新绘制曲线图,最好加一下深度监视也就是{ deep: true }
那么获取echarts图的高度呢,用到了vueuse这个插件中的useElementSize,它可以获取dom元素的高度和宽度,注意,它获取的是echarts图父节点的高度,因为echarts很难搞,没有图片的时候,节点根本就没有渲染,根本就获取不到speed这个dom元素,所以只能给一个父元素,通过设置与父元素相同的高度来显示图
大致是这么个流程,不过需要根据实际项目来理解会更容易一些
另外,可以看到,drawChart这个方法我是封装在插件中的,可以看下我插件是怎么写的
二、插件中的写法
import axios from "axios";
import * as echarts from 'echarts'
export const drawChart = (index, ref, height=260) => {
axios
.get("static/json/speed.json")
.then((res) => {
const all_data = res.data[index];
// console.log(all_data)
const x = [];
const data = [];
for (let i = 0; i < all_data.length; i++) {
x.push(all_data[i].time);
// const {sgqs, swrs, ssrs} = all_data[i]
// const datai = {sgqs, swrs, ssrs}
const datai = { 纵向速度: all_data[i].speed };
data.push(datai);
}
const keyArray = Object.keys(data[0]);
const series = [];
keyArray.forEach((key) => {
series.push({
name: key,
data: data.map((item) => item[key]),
type: "line",
smooth: true,
});
});
// console.log(series)
const options = {
title: { text: "车辆速度变化情况" },
tooltip: {
// 鼠标悬浮提示框显示 X和Y 轴数据
trigger: "axis",
backgroundColor: "rgba(32, 33, 36,.7)",
borderColor: "rgba(32, 33, 36,0.20)",
// borderWidth: 1,
textStyle: {
// 文字提示样式
color: "#fff",
fontSize: "12",
},
axisPointer: {
// 坐标轴虚线
type: "cross",
label: {
backgroundColor: "#6a7985",
},
},
},
xAxis: {
data: x,
type: "category",
},
yAxis: {},
legend: {
data: keyArray,
},
series,
};
const chart_line = echarts.init(ref);
chart_line.resize({height})
chart_line.setOption(options);
window.addEventListener("resize", () => {
chart_line.resize();
});
})
.catch((err) => {
console.log(err);
});
};
drawChart需要三个参数,数据索引,需要显示图片的dom,以及图的高度
这三个元素都由组件传递,不过高度有默认值,就是260px,不过会根据你的实际窗口大小变化的,因为我的el-card的高度也是变化的
这个方法做了如下几件事:
- axios获取数据
- 根据index值取出需要的数据(其实这个事儿该后端做)
- 处理echarts需要的数据
- 根据输入的dom参数初始化dom
- 根据输入的height来设置图的高度
- echarts设置option
- 监听窗口变化,改变窗口大小
三、几个问题
其实根据上面的解决方案,已经大致解决了,但是还有几个小问题
- 重绘图的时候,控制台会报警说原来的dom上有图片,所以每次重绘之前,其实应该判断dom是否存在
- 插件中第7步resize的时候,并没有给参数