You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
93 lines
2.0 KiB
Vue
93 lines
2.0 KiB
Vue
2 weeks ago
|
<script setup lang="ts">
|
||
|
import { onMounted, onUnmounted, ref, watch } from "vue";
|
||
|
import * as echarts from "echarts";
|
||
|
|
||
|
const props = defineProps({
|
||
|
data: {
|
||
|
type: Array as PropType<Array<{ value: number; name: string }>>,
|
||
|
required: true,
|
||
|
},
|
||
|
colors: { type: Array as PropType<Array<string>>, default: () => [] },
|
||
|
});
|
||
|
|
||
|
const chartContainer = ref<HTMLDivElement | null>(null);
|
||
|
let chartInstance: echarts.ECharts | null = null;
|
||
|
const colorsArr = ['#3FE3FA','#FF4D00']
|
||
|
// 初始化图表
|
||
|
const initChart = () => {
|
||
|
if (!chartContainer.value) return;
|
||
|
chartInstance = echarts.init(chartContainer.value);
|
||
|
setTimeout(() => {
|
||
|
chartInstance?.resize();
|
||
|
updateChart();
|
||
|
}, 500);
|
||
|
};
|
||
|
|
||
|
// 更新图表配置
|
||
|
const updateChart = () => {
|
||
|
if (!chartInstance) return;
|
||
|
|
||
|
chartInstance.setOption({
|
||
|
legend: {
|
||
|
type: "scroll",
|
||
|
orient: "vertical",
|
||
|
left: "70%",
|
||
|
align: "left",
|
||
|
top: "middle",
|
||
|
itemWidth: 16, // 图例项宽度
|
||
|
itemHeight: 8,
|
||
|
textStyle: { color: "#FFF" },
|
||
|
},
|
||
|
series: [
|
||
|
{
|
||
|
type: "pie",
|
||
|
radius: ["40%", "80%"],
|
||
|
center: ["35%", "50%"],
|
||
|
label: { show: false },
|
||
|
itemStyle: {
|
||
|
color: (params) =>
|
||
|
new echarts.graphic.LinearGradient(0, 0, 1, 0, [
|
||
|
{ offset: 0, color: props.colors[params.dataIndex] },
|
||
|
{ offset: 1, color: colorsArr[params.dataIndex] },
|
||
|
]),
|
||
|
},
|
||
|
data: props.data,
|
||
|
},
|
||
|
],
|
||
|
});
|
||
|
};
|
||
|
|
||
|
// 生命周期管理
|
||
|
onMounted(() => {
|
||
|
initChart();
|
||
|
});
|
||
|
|
||
|
onUnmounted(() => {
|
||
|
if (chartInstance) {
|
||
|
chartInstance.dispose();
|
||
|
chartInstance = null;
|
||
|
}
|
||
|
});
|
||
|
|
||
|
// 响应式更新
|
||
|
watch(
|
||
|
() => props.data,
|
||
|
async () => {
|
||
|
await nextTick();
|
||
|
updateChart();
|
||
|
}
|
||
|
);
|
||
|
|
||
|
// 窗口大小监听
|
||
|
// onMounted(() => {
|
||
|
// window.addEventListener("resize", () => chartInstance?.resize());
|
||
|
// });
|
||
|
|
||
|
// onUnmounted(() => {
|
||
|
// window.removeEventListener("resize", () => chartInstance?.resize());
|
||
|
// });
|
||
|
</script>
|
||
|
<template>
|
||
|
<div ref="chartContainer" style="width: 100%; height: 100%" />
|
||
|
</template>
|