step.1 按需引入
// plugins/echarts
import * as echarts from "echarts/core";
import { BarChart, PieChart, LineChart } from "echarts/charts";
import { TooltipComponent, GridComponent, LegendComponent, TitleComponent } from "echarts/components";
import { CanvasRenderer, SVGRenderer } from "echarts/renderers";
import echartsTheme from "./echartsTheme";
// import eventBus from "@/libs/eventBus";
// let echartsThemeKey = 1;
// 注入自定义主题
echarts.registerTheme("customed", echartsTheme);
// 注册必须的组件
echarts.use([BarChart, PieChart, TooltipComponent, GridComponent, LegendComponent, TitleComponent, CanvasRenderer, SVGRenderer, LineChart]);
export default echarts;
step.2 配置全局自定义样式
// plugins/echartsTheme
const echartsTheme = {
color: ["#07C3FF", "#FFB821", "#FF6A98", "#F2877F", "#958EED", "#FFA5D6", "#fc8452", "#9a60b4", "#ea7ccc"],
backgroundColor: "rgba(0, 0, 0, 0)",
textStyle: {},
title: {
textStyle: {
color: "#D9E7FF",
},
subtextStyle: {
color: "#6E7079",
},
},
bar: {
..
},
pie: {
...
},
// 类目轴
categoryAxis: {
...
},
// 数值轴
valueAxis: {
.....
},
toolbox: {
...
},
// 图例
legend: {
...
},
// 提示框
tooltip: {
axisPointer: {
lineStyle: {
color: "#ccc",
width: px1,
},
crossStyle: {
color: "#ccc",
width: px1,
},
},
textStyle: {
color: "#D9E7FF",
fontSize: px12,
},
backgroundColor: "rgba(3, 41, 55, 0.8)",
borderColor: "#4ba9f5",
padding: [px10, px10],
borderWidth: px1,
extraCssText: `border-radius:${px8}px;`,
},
dataZoom: {
...
},
markPoint: {
...
},
};
export default echartsTheme;
step.3 基础渲染&卸载钩子
// useEcharts.js
// 可以在此钩子中添加eventBus~
import echarts from "@/plugins/echarts";
import { onBeforeUnmount, onMounted, ref, shallowRef } from "vue";
export default () => {
let tempOption = null;
const chartRef = ref(null),
chartObj = shallowRef(null);
/**
* @description: 载入echarts
*/
function init(themeName = "customed") {
if (chartRef.value) {
chartObj.value = echarts.init(chartRef.value, themeName, { renderer: "svg" });
// console.log(chartObj);
}
}
/**
* @description: 销毁echarts
* @return {*}
*/
function dispose() {
if (chartObj.value) chartObj.value?.dispose();
}
function setOption(option) {
tempOption = option;
chartObj.value?.setOption(option, true);
}
onMounted(() => {
init();
});
onBeforeUnmount(() => {
dispose();
});
return {
chartRef, // ref
setOption,// 传入option配置来渲染chart
chartObj, // 实例对象
};
};
step.4 自动播放钩子
// useChartAutoplay.js
/*
* @Desc:自动播放通用hook 在获取数据后使用
*/
import { computed, onBeforeUnmount, ref } from "vue";
// showTip 自动播放是否显示提示框
// showHighlight 自动播放是否显示高亮
// customPlayFn 自动播放时的自定义fn
export default ({ chartObj, delay = 3000, showTip = false, showHighlight = false, customPlayFn = null }) => {
let timer = null,
maxIndex = 0;
const activeIndex = ref(0),
isSuspend = ref(false),
preIndex = computed(() => {
return activeIndex.value - 1 < 0 ? maxIndex : activeIndex.value - 1;
});
function createAutoPlay(dataLength) {
if (timer) {
clearAutoplay();
}
maxIndex = dataLength - 1;
setMouseoverEvent();
autoplayFn();
timer = setInterval(() => {
// console.log("12312321");
if (!isSuspend.value) {
activeNext();
autoplayFn();
}
}, delay);
}
/**
* @description: 播放处理
*/
function autoplayFn() {
if (customPlayFn) {
customPlayFn();
}
if (showTip) {
handleShowTip(activeIndex.value);
}
if (showHighlight) {
handleHideHighlight(preIndex.value);
handleShowHighlight(activeIndex.value);
}
}
/**
* @description: 显示提示框
* @param {*} dataIndex
* @param {*} seriesIndex
*/
function handleShowTip(dataIndex = 0, seriesIndex = 0) {
chartObj.value?.dispatchAction({
type: "showTip",
seriesIndex: seriesIndex,
playState: true,
dataIndex: dataIndex,
});
}
/**
* @description: 显示高亮
* @param {*} dataIndex
* @param {*} seriesIndex
*/
function handleShowHighlight(dataIndex = 0, seriesIndex = 0) {
chartObj.value?.dispatchAction({
type: "highlight",
playState: true,
seriesIndex: seriesIndex,
dataIndex: dataIndex,
});
}
/**
* @description: 关闭高亮
* @param {*} dataIndex
* @param {*} seriesIndex
*/
function handleHideHighlight(dataIndex = 0, seriesIndex = 0) {
chartObj.value?.dispatchAction({
type: "downplay",
playState: true,
seriesIndex: seriesIndex,
dataIndex: dataIndex,
});
}
/**
* @description: 设置当前激活index
* @param {number} index
*/
function setActiveIndex(index) {
activeIndex.value = index;
}
/**
* @description: 激活下一个
*/
function activeNext() {
// console.log(maxIndex);
activeIndex.value = activeIndex.value + 1 > maxIndex ? 0 : activeIndex.value + 1;
}
function setMouseoverEvent() {
// 鼠标移入 暂停
chartObj.value?.on("mouseover", () => {
isSuspend.value = true;
});
// 鼠标移除 不暂停
chartObj.value?.on("globalout", () => {
isSuspend.value = false;
});
}
/**
* @description: 清除自动播放
*/
function clearAutoplay() {
activeIndex.value = 0;
clearInterval(timer);
}
onBeforeUnmount(() => {
if (timer) clearInterval(timer);
});
return {
activeIndex,
isSuspend,
createAutoPlay, // 创建自动播放,入参为数据长度
};
};
step.5 使用
/*
* @Desc:
*/
import useBarChart from "@/libs/use/useEcharts";
import useChartAutoPlay from "@/libs/use/useChartAutoPlay";
import { getVerticalGradient } from "@/utils/echarts";
export default () => {
const { chartRef, setOption, chartObj } = useBarChart();
const { createAutoPlay } = useChartAutoPlay({
chartObj: chartObj,
showTip: true,
});
const option = {
从echarts复制的option配置
};
function setCategory(arr) {
option.xAxis.data = arr;
}
function createData(arr) {
...数据处理部分
setOption(option);
createAutoPlay(dataLength);
}
return {
chartRef,
setCategory,
createData,
};
};
step.6 在组件中使用
// some component hook
import useAreaLineChart from "@/libs/echarts/useXxxxChart";
import { onMounted } from "vue";
export default () => {
const { chartRef, setCategory, createData } = useXxxxChart();
function setData() {
setTimeout(() => {
setCategory(["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"]);
createData([
{
name: "总数",
data: [11, 22, 33, 44, 55, 55, 55, 55, 55, 55, 55, 55],
},
{
name: "完成数",
data: [4, 3, 5, 5, 6, 7, 8, 9, 10, 11, 12, 2],
},
]);
});
}
onMounted(() => {
setData();
});
return {
chartRef,
};
};
// template
<div ref="chartRef"></div>