ECharts,一个使用 JavaScript 实现的开源可视化库,可以流畅的运行在 PC 和移动设备上,兼容当前绝大部分浏览器(IE9/10/11,Chrome,Firefox,Safari等),底层依赖矢量图形库 ZRender,提供直观,交互丰富,可高度个性化定制的数据可视化图表。
ECharts 提供了常规的折线图、柱状图、散点图、饼图、K线图,用于统计的盒形图,用于地理数据可视化的地图、热力图、线图,用于关系数据可视化的关系图、treemap、旭日图,多维数据可视化的平行坐标,还有用于 BI 的漏斗图,仪表盘,并且支持图与图之间的混搭。
官网地址:
Apache EChartsECharts, a powerful, interactive charting and visualization library for browserhttps://echarts.apache.org/zh/index.html 截至发文前echarts已经更新至5.3版本。版本得尤为注意,因为echarts各个版本之间的api差距较大,时常会出现旧版本api在新版本未作保留而被替换然后warring的情况,也有版本不兼容导致项目运行失败的情况。
npm安装:
npm install echarts --save
一、echarts的引入
Echarts不管是在React还是Vue框架下的引入可以分为全量引入和按需引入。
全量引入是指将echarts所需要的所有图表资源比如柱状图饼图在使用图表的时候全部引入进去,可能展示的仅仅是echarts下的一个柱状图而已。此种引入方式适合项目使用了多个图表类型展示数据的时候。但是在打包的时候往往echarts会占据很大一部分体积。
按需引入是指按照显示的图表类型去对应的引入echarts里面的资源,比如使用柱状图就从echarts里面引入柱状图所需要的资源,饼图就引入饼图做需要的。此种引入方式适合少部分使用echarts的项目,此种引入方式虽然麻烦但是会大大缩小打包体积和图表的加载效率。
两者的加载效率可以参考下图的控制台性能分析:
前者为全量引入,后者为按需引入:
可以看出相同echarts图,全量引入花费时间 3009ms,按需引入花费1988ms,时间直接减少了三分之一。而且全量引入还会引入一些用不到的组件比如下图中的dataZoom就没在页面上用到,但浏览器还是将其加载了:
可能对于个别echarts图,两种引入方式渲染的差别可以忽略不计,但是对于数据量比较大的echarts图来说,这两种引入方式的渲染差异就很大了。
1.echarts全量引入:
echarts在Vue中是在main.js中进行echarts的引入:
import Vue from 'vue'
import App from './App.vue'
import * as echarts from 'echarts'; // ehcarts5.x版本引入方式
// import echarts from 'echarts'; // ehcarts4.x版本引入方式
Vue.prototype.$echarts = echarts;
Vue.config.productionTip = false
new Vue({
render: h => h(App),
}).$mount('#app')
也可以直接在组件中进行echarts的引入:(此方法也是react中全量引入的方法)
import * as echarts from 'echarts'; // ehcarts5.x版本引入方式
// import echarts from 'echarts'; // ehcarts4.x版本引入方式
2.echarts按需引入:
适用于react和Vue(针对本例的柱状图而言):
// 引入 echarts 核心模块,核心模块提供了 echarts 使用必须要的接口。
import * as echarts from 'echarts/core';
// 引入柱状图图表,图表后缀都为 Chart
import { BarChart } from 'echarts/charts';
// 引入提示框,标题,直角坐标系,数据集,内置数据转换器组件,组件后缀都为 Component
import {
TitleComponent,
TooltipComponent,
GridComponent,
DatasetComponent,
TransformComponent
} from 'echarts/components';
// 标签自动布局,全局过渡动画等特性
import { LabelLayout, UniversalTransition } from 'echarts/features';
// 引入 Canvas 渲染器,注意引入 CanvasRenderer 或者 SVGRenderer 是必须的一步
import { CanvasRenderer } from 'echarts/renderers';
// 注册必须的组件
echarts.use([
TitleComponent,
TooltipComponent,
GridComponent,
DatasetComponent,
TransformComponent,
BarChart,
LabelLayout,
UniversalTransition,
CanvasRenderer
]);
3.vue中echarts按需引入Ts版本:
适用于reactHook和Vue3【TS】(针对本例的柱状图而言):
import * as echarts from 'echarts/core';
import {
BarChart,
// 系列类型的定义后缀都为 SeriesOption
BarSeriesOption,
LineChart,
LineSeriesOption
} from 'echarts/charts';
import {
TitleComponent,
// 组件类型的定义后缀都为 ComponentOption
TitleComponentOption,
TooltipComponent,
TooltipComponentOption,
GridComponent,
GridComponentOption,
// 数据集组件
DatasetComponent,
DatasetComponentOption,
// 内置数据转换器组件 (filter, sort)
TransformComponent
} from 'echarts/components';
import { LabelLayout, UniversalTransition } from 'echarts/features';
import { CanvasRenderer } from 'echarts/renderers';
// 通过 ComposeOption 来组合出一个只有必须组件和图表的 Option 类型
type ECOption = echarts.ComposeOption<
| BarSeriesOption
| LineSeriesOption
| TitleComponentOption
| TooltipComponentOption
| GridComponentOption
| DatasetComponentOption
>;
// 注册必须的组件
echarts.use([
TitleComponent,
TooltipComponent,
GridComponent,
DatasetComponent,
TransformComponent,
BarChart,
LabelLayout,
UniversalTransition,
CanvasRenderer
]);
const option: ECOption = {
// ...
};
按需引入参考官方链接:
Handbook - Apache EChartshttps://echarts.apache.org/handbook/zh/basics/import/
二、Vue中使用Echarts
1.vue2中使用echarts
echarts的工作机制是首先获取到dom节点,然后将echarts图渲染到该dom节点上。但是对于dom节点的获取也有很多种方式,传统的就是给节点定义一个id,然后使用id获取到该dom节点:
// 使用id获取dom节点,初始化echarts实例
this.myChart = this.$echarts.init(document.getElementById('myChart'));
但是此方法缺点也很显著,因为id在页面中得是唯一的。当该echarts图是个复用组件的时候,就得通过props将id传入组件中进行挂载:
但是这个是完全可以避免的,那就是用ref方式进行节点挂载:
// dom节点
<template>
<div class="chart" ref="myChart"/>
</template>
// 基于准备好的dom,初始化echarts实例
this.myChart = this.$echarts.init(this.$refs.myChart);
所以综上所述,理想的在Vue2中引入echarts的代码示例应该如下:
<template>
<div class="chart" ref="myChart"/>
</template>
<script>
// 将option配置项单独独立出来方便后续维护
import option from './config'
export default {
name: 'MyChart',
data(){
return{
myChart:null
}
},
mounted() {
// 节点加载完成后开始进行节点挂载和echarts渲染
this.$nextTick(()=>{
this.chartInit()
// 添加监听方法,当页面放大缩小时触发echarts重绘,以适配改变后的页面
window.addEventListener("resize", () => {
this.myChart && this.myChart.resize();
});
})
},
// 组件销毁前卸载监听方法
beforeDestroy() {
window.removeEventListener("resize", () => {
this.myChart && this.myChart.resize();
});
},
methods: {
chartInit(){
// 基于准备好的dom,初始化echarts实例
this.myChart = this.$echarts.init(this.$refs.myChart);
// 使用刚指定的配置项和数据显示图表。
this.myChart.setOption(option,true);
}
},
}
</script>
<style scoped>
.chart {
width: 100%;
height: 500px;
}
</style>
option.js配置项:
// 指定图表的配置项和数据
export default {
title: {
text: 'ECharts 入门示例'
},
tooltip: {},
legend: {
data: ['销量']
},
xAxis: {
data: ['衬衫', '羊毛衫', '雪纺衫', '裤子', '高跟鞋', '袜子']
},
yAxis: {},
series: [
{
name: '销量',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}
]
}
项目结构:
展示效果:
2.Vue3中使用echarts(ts版本)
如上所述,在vue3中使用ref进行挂载的最佳示例如下:
使用ref进行节点挂载,同样的配置项存储在config.tsx之中。
<template>
<div ref="myChart" class="myChart" />
</template>
<script lang="ts" setup>
import { onBeforeUnmount, onMounted, ref } from "vue";
import * as echarts from "echarts";
import options from "./config";
// 节点ref存放
const chartRef = ref<HTMLElement | null>(null);
// echarts实例存放
let chart: echarts.ECharts | null = null;
const chartInit = () => {
if (chartRef.value) {
chart = echarts.init(chartRef.value);
// 使用刚指定的配置项和数据显示图表。
chart.setOption(options, true);
}
};
onMounted(() => {
chartInit();
// 添加监听方法,当页面放大缩小时触发echarts重绘,以适配改变后的页面
window.addEventListener("resize", () => {
chart && chart.resize();
});
});
// 组件销毁前卸载监听方法
onBeforeUnmount(() => {
window.removeEventListener("resize", () => {
chart && chart.resize();
});
});
</script>
<style lang="less" scoped>
.myChart {
width: 100%;
height: 500px;
}
</style>
config.tsx:
export default {
title: {
text: "ECharts 入门示例",
},
tooltip: {},
xAxis: {
data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"],
},
yAxis: {},
series: [
{
name: "销量",
type: "bar",
data: [5, 20, 36, 10, 10, 20],
},
],
};
项目结构:
展示效果:
三、React中使用Echarts
1.ReactClass类中使用echarts
示例代码(index.js):
import * as echarts from "echarts";
import styles from './index.less';
import options from "./config";
class MyChart extends PureComponent {
constructor(props) {
super(props);
this.state = {
};
// echarts实例存放
this.chart = null;
// ref节点实例存放
this.chartRef = React.createRef()
}
componentDidMount() {
this.chartInit();
// 添加监听方法,当页面放大缩小时触发echarts重绘,以适配改变后的页面
window.addEventListener("resize", () => {
this.chart && this.chart.resize();
});
}
chartInit = ()=> {
this.chart = echarts.init(chartRef.value);
// 使用刚指定的配置项和数据显示图表。
this.chart.setOption(options, true);
}
// 组件销毁前卸载监听方法
componentWillUnmount() {
window.removeEventListener("resize", () => {
this.chart && this.chart.resize();
});
}
render() {
return (
<div ref={this.chartRef} class="style.myChart" />
);
}
}
export default MyChart;
option.js和结构都跟vue差不多,效果图参考Vue下运行效果图。
2.ReactHook钩子中使用echarts
示例代码(index.js):
import React, { useEffect, useRef } from 'react';
import * as echarts from "echarts";
import styles from './index.less';
import options from "./config";
const MyChart: React.FC<any> = (props) => {
// echarts实例存放
const chart = null;
// ref节点实例存放
const chartRef = useRef(null)
const chartInit = ()=> {
chart = echarts.init(chartRef.current);
// 使用刚指定的配置项和数据显示图表。
chart.setOption(options, true);
}
useEffect(() => {
chartInit();
// 添加监听方法,当页面放大缩小时触发echarts重绘,以适配改变后的页面
window.addEventListener("resize", () => {
chart && chart.resize();
});
// 组件销毁前卸载监听方法
return () => {
window.removeEventListener("resize", () => {
chart && chart.resize();
});
}
}, [])
return <div ref={f => { chartRef.current = f }} class="style.myChart" />
}
export default MyChart;
option.js和结构都跟vue差不多,效果图参考Vue下运行效果图。