一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第4天,点击查看活动详情。
序
分享在项目中使用Echarts
的技巧和一些图表案例
本文内容Echarts
、Vue3
、TypeScript
结合使用
主观性较强,或许对你有帮助。
封装Echarts全局组件
Echarts
的安装和引入,参照官网,官网已经有全局使用和按需使用的详细说明
之前使用TypeScript
,不太清楚可以给option
什么类型,现在回看官网就明白了
开始在components
文件夹下创建echarts
组件
echarts
中options
的类型
echarts
中options
的类型如下
type ECOption
就是options
的类型
import * as echarts from "echarts";
import { BarSeriesOption, LineSeriesOption } from "echarts/charts";
import {
TitleComponentOption,
TooltipComponentOption,
GridComponentOption,
DatasetComponentOption
} from "echarts/components";
export type ECOption = echarts.ComposeOption<
| BarSeriesOption
| LineSeriesOption
| TitleComponentOption
| TooltipComponentOption
| GridComponentOption
| DatasetComponentOption
>;
defineComponent
版本
需要注意的是options
的默认值是Function
在组件销毁时,要移除window
中resize
调用的事件
还有在初始化echarts
,获取dom
元素时,即便在onMounted
事件中,也会有ts
的警告,
需要用到!
非空断言操作符
<template>
<div :id="id" class="echart-div"></div>
</template>
<script lang="ts">
import { defineComponent, onMounted, onUnmounted, PropType, ref, toRefs, watch } from "vue";
import * as echarts from "echarts";
import { ECOption } from "@/types/interface";
export default defineComponent({
props: {
id: {
type: String,
default: "echartDiv"
},
options: {
type: Object as PropType<ECOption>,
default: Function
},
theme: {
type: String,
default: ""
}
},
setup(props) {
const { options, id, theme } = toRefs(props);
let chartDom: echarts.EChartsType | null = null;
const handleOptionsChange = () => {
if (chartDom != null) {
chartDom.setOption({ ...options.value });
}
};
const handleChartResize = () => {
if (chartDom != null) {
chartDom.resize();
}
};
onMounted(() => {
chartDom = echarts.init(document.getElementById(id.value)!, theme.value);
chartDom.setOption({ ...options.value });
window.addEventListener("resize", () => {
handleChartResize();
});
});
onUnmounted(() => {
window.removeEventListener("resize", () => {
handleChartResize();
});
});
watch(
() => options.value,
() => {
handleOptionsChange();
},
{ deep: true }
);
return {};
}
});
</script>
<style scoped>
.echart-div {
width: 100%;
height: 100%;
}
</style>
script setup
版本
script setup
语法看起来更加简约
<script setup lang="ts">
import { onMounted, onUnmounted, PropType, ref, toRefs, watch } from "vue";
import * as echarts from "echarts";
import { ECOption } from "@/types/interface";
const props = defineProps({
id: {
type: String,
default: "echartDiv"
},
options: {
type: Object as PropType<ECOption>,
default: Function
},
theme: {
type: String,
default: ""
}
});
let chartDom: echarts.EChartsType | null = null;
const handleOptionsChange = () => {
if (chartDom != null) {
chartDom.setOption({ ...props.options });
}
};
const handleChartResize = () => {
if (chartDom != null) {
chartDom.resize();
}
};
onMounted(() => {
chartDom = echarts.init(document.getElementById(props.id)!, props.theme);
chartDom.setOption({ ...props.options });
window.addEventListener("resize", () => {
handleChartResize();
});
});
onUnmounted(() => {
window.removeEventListener("resize", () => {
handleChartResize();
});
});
watch(
() => props.options,
() => {
handleOptionsChange();
},
{ deep: true }
);
</script>
个人的想法是,echarts
全局组件只做图表的初始化,监听options
的变化更新图表,监听window
的resize
事件让图表也resize
图表是怎样的完全取决于options
的数据,详细看案例分享
注册全局组件
参考我之前的文章Vue项目中的实用技巧记录 - 掘金 (juejin.cn)
已分为webpack
和vite
两种情况下如何自动注册全局组件
欢迎点赞分享
使用案例
基本使用
使用柱状图展示使用的案例
<script setup lang="ts">
import { reactive } from "vue";
import EchartsComponent from "@/components/echartsComponent.vue";
import { ECOption } from "@/types/interface";
const lightOptions = reactive({
title: {
text: "主题Demo"
},
tooltip: {},
xAxis: {
data: ["衬衫", "羊毛衫", "雪纺衫", "裤子", "高跟鞋", "袜子"]
},
yAxis: {},
series: [
{
name: "销量",
type: "bar",
data: [5, 20, 36, 10, 10, 20]
}
]
} as ECOption);
setTimeout(() => {
lightOptions.series = {
name: "销量",
type: "bar",
data: [0, 0, 1, 10, 20, 30]
};
}, 1000);
</script>
<template>
<div class="container">
<!-- 亮色主题 -->
<EchartsComponent :id="'lightTheme'" :options="lightOptions" class="echarts-demo light-theme"> </EchartsComponent>
<!-- 黑暗主题 -->
<EchartsComponent
:id="'darkTheme'"
:options="lightOptions"
:theme="'dark'"
class="echarts-demo dark-theme"
></EchartsComponent>
</div>
</template>
<style lang="scss" scoped>
.container {
display: flex;
}
.echarts-demo {
height: 300px;
width: 40%;
margin: 20px;
}
</style>
效果图如下
环形进度图
之前项目遇到类似的ui设计,原本想用echarts
实现,最后还是别的同事用canvas
实现了
这次参考了 分享你我 的案例实现了
<script setup lang="ts">
import { reactive } from "vue";
import EchartsComponent from "@/components/echartsComponent.vue";
import { ECOption } from "@/types/interface";
import * as echarts from "echarts";
const chartData = {
total: 100,
value: 77
};
const total = chartData.total;
const value = [chartData.value];
const color = "rgba(149, 212, 117)";
const bgColor = "rgba(149, 212, 117,.1)";
const lightOptions = reactive({
angleAxis: {
max: total,
clockwise: true, // 逆时针
show: false // 隐藏刻度线
},
radiusAxis: {
type: "category",
show: true,
axisLabel: {
show: false
},
axisLine: {
show: false
},
axisTick: {
show: false
}
},
polar: {
center: ["50%", "50%"],
radius: "100%" //图形大小
},
series: [
{
stack: "round",
type: "bar",
data: value,
showBackground: false,
coordinateSystem: "polar",
roundCap: true,
barWidth: 15,
silent: true,
itemStyle: {
normal: {
color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
{
offset: 0,
color: bgColor
},
{
offset: 1,
color: color
}
])
}
}
},
{
stack: "round",
type: "bar",
data: [0.01],
showBackground: false,
backgroundStyle: {
shadowColor: "rgba(0, 0, 0, 0.2)",
shadowBlur: 10,
shadowOffsetY: 2
},
coordinateSystem: "polar",
roundCap: true,
barWidth: 15,
itemStyle: {
color: color,
borderColor: color,
borderWidth: 5
}
}
]
} as ECOption);
</script>
<template>
<div class="container">
<!-- 亮色主题 -->
<EchartsComponent :id="'lightRing'" :options="lightOptions" class="echarts-demo light-theme"> </EchartsComponent>
<!-- 黑暗主题 -->
<EchartsComponent
:id="'darkRing'"
:options="lightOptions"
:theme="'dark'"
class="echarts-demo dark-theme"
></EchartsComponent>
</div>
</template>
<style lang="scss" scoped>
.container {
display: flex;
}
.echarts-demo {
height: 300px;
width: 40%;
margin: 20px;
}
</style>
效果图如下
其他案例
待更新
详细代码
LWH/vite-vue3-project (gitee.com)
详细代码在src/views/echarts
和src/components
文件夹中