本文基于Vue3整合Apache ECharts,封装为单独的组件供其它页面调用。
在任意页面打开命令行窗口,输入以下命令全局安装Vue CLI
npm install -g @vue/cli
在自己的开发目录下,通过如下命令创建一个Vue原型项目
# 此处在D盘Vue目录下操作
vue create demo-project
默认选择第一个,按下回车创建Vue 3项目
显示以下页面表示Vue3项目创建成功
在工作目录下,输入以下命令进行全局安装
npm install echarts -S
用Visual Studio Code打开项目,Visual Studio Code官网下载地址,打开后,可以看到项目目录:
其中,我们主要在src目录下编写我们的前端代码。
按住 ctrl+` 快捷键,打开终端输入命令运行项目
npm run serve
浏览器打开输入网址http://localhost:8080/
,显示以下界面则表示项目搭建成功,接下来开始编写代码:
首先Apache ECharts访问官网https://echarts.apache.org/zh/index.html,打开主页面点击快速入门,这里不多赘述,可结合网上视频进行参考学习
接下来根据自己的需求选择自己的图表,点击所有实例,此处就先随便找一个看着高大尚的图来进行操作:
点击后,在最左面选择代码编辑处的代码,复制option内的所有数据 (一定要复制全,别漏掉数据),我们先抽取出来,一会定义实时响应式数据会用到
首先我们在components
目录下创建MyChart.vue
文件作为单独的图表组件,一会我们在App.vue
中引入我们的图表组件
以下为图表组件代码,主要功能我们一会介绍。
<template>
<br/>
<div>
<button @click="changeData">改变数据button>
<span> span>
<button @click="recoveryData">恢复数据button>
div>
<div id="myEChart" style='height: 500px; width: auto;'>div>
template>
<script>
// 导入echarts依赖
import * as echarts from 'echarts'
import { onMounted, reactive } from 'vue';
export default {
data() {
return {};
},
setup() {
// 在组件挂载的时候,初始化图表信息
onMounted(() => {
// Echarts重新加载数据但不重新渲染的原因和解决方法
document.getElementById("myEChart").setAttribute('_echarts_instance_', '');
let myChart = echarts.init(document.getElementById("myEChart"));
getChartSetting().then(() => {
myChart.setOption(option);
});
window.addEventListener("resize", function () {
myChart.resize();
});
});
let scheduleList = reactive([]);
let option = reactive({
tooltip: {
trigger: 'axis',
axisPointer: {
type: 'shadow'
}
},
legend: {},
grid: {
left: '3%',
right: '4%',
bottom: '3%',
containLabel: true
},
xAxis: [
{
type: 'category',
data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun']
}
],
yAxis: [
{
type: 'value'
}
],
series: [
{
name: 'Direct',
type: 'bar',
emphasis: {
focus: 'series'
},
data: [320, 332, 301, 334, 390, 330, 320]
},
{
name: 'Email',
type: 'bar',
stack: 'Ad',
emphasis: {
focus: 'series'
},
data: [120, 132, 101, 134, 90, 230, 210]
},
{
name: 'Union Ads',
type: 'bar',
stack: 'Ad',
emphasis: {
focus: 'series'
},
data: [220, 182, 191, 234, 290, 330, 310]
},
{
name: 'Video Ads',
type: 'bar',
stack: 'Ad',
emphasis: {
focus: 'series'
},
data: [150, 232, 201, 154, 190, 330, 410]
},
{
name: 'Search Engine',
type: 'bar',
data: [862, 1018, 964, 1026, 1679, 1600, 1570],
emphasis: {
focus: 'series'
},
markLine: {
lineStyle: {
type: 'dashed'
},
data: [[{ type: 'min' }, { type: 'max' }]]
}
},
{
name: 'Baidu',
type: 'bar',
barWidth: 5,
stack: 'Search Engine',
emphasis: {
focus: 'series'
},
data: [620, 732, 701, 734, 1090, 1130, 1120]
},
{
name: 'Google',
type: 'bar',
stack: 'Search Engine',
emphasis: {
focus: 'series'
},
data: [120, 132, 101, 134, 290, 230, 220]
},
{
name: 'Bing',
type: 'bar',
stack: 'Search Engine',
emphasis: {
focus: 'series'
},
data: [60, 72, 71, 74, 190, 130, 110]
},
{
name: 'Others',
type: 'bar',
stack: 'Search Engine',
emphasis: {
focus: 'series'
},
data: [62, 82, 91, 84, 109, 110, 120]
}
]
});
function changeData() {
console.log("进入修改函数");
scheduleList = ['星期一', '星期二', '星期三', '星期四', '星期五', '星期六', '星期日'];
option.xAxis[0].data = scheduleList;
refreshChart();
}
function recoveryData() {
console.log("进入恢复函数");
scheduleList = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
option.xAxis[0].data = scheduleList;
refreshChart();
}
function refreshChart() {
console.log("进入刷新图表函数");
// Echarts重新加载数据但不重新渲染的原因和解决方法
document.getElementById("myEChart").setAttribute('_echarts_instance_', '');
let myChart = echarts.init(document.getElementById("myEChart"));
myChart.setOption(option);
}
// 获取echart数据函数
async function getChartSetting() {
scheduleList = ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'];
option.xAxis[0].data = scheduleList;
// 之前的案例参考
// const url = `${BASE_URL}/selectdata`;
// console.log("selectdata");
// res = await $axios({
// url,
// method: "post",
// });
// scheduleList = res.map(v => v.schedule);
// option.xAxis[0].data = scheduleList;
}
return {
changeData,
recoveryData,
option,
scheduleList,
getChartSetting,
}
},
methods: {
},
}
script>
还是话不多说,直接上App.vue
代码
<template>
<button v-if="isShow" @click="reverse">图表隐藏button>
<button v-if="!isShow" @click="reverse">图表显示button>
<br/>
<div v-if="isShow">
<MyChart/>
div>
template>
<script>
import MyChart from './components/MyChart.vue'
import { ref } from 'vue';
export default {
name: 'App',
setup() {
// isShow变量表示图形的显示与隐藏
let isShow = ref(true);
function reverse() {
isShow.value = !isShow.value
}
return {
reverse,
isShow
}
},
components: {
MyChart
}
}
script>
<style>
#app {
font-family: Avenir, Helvetica, Arial, sans-serif;
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
text-align: center;
color: #2c3e50;
margin-top: 60px;
}
style>
总算要解释一下上面的代码功能了,可以按照功能比对代码注释来理解代码。
以下是代码运行时的主页面:
当图表dom元素销毁重建时,对应图表数据不能实时更新,出现改问题首先需要介绍一下Echarts的渲染逻辑
渲染逻辑:
如果echarts未实例化则进行实例化过程,一旦实例化,便会在div容器生成一个 echarts_instance 属性, 该属性值即为当前echarts的ID,然后根据该ID进行渲染。
数据重新渲染的原因:
第一次渲染图表后,便有了ID,但是我们非第一次加载数据时,图表的_echarts_instance_属性值我们没有显式引用,所以此时,待渲染的图表在原有的div容器中,匹配不到想要渲染的图表,则出现数据加载成功,但是不渲染的情况。
解决方案:
先全局刷新div,然后渲染 ,这样保证了每次加载的div中的图表ID【即_echarts_instance_】为默认值;再重新生成图表即可!
document.getElementById('div的ID').setAttribute('_echarts_instance_', '');