象形柱状图(Vue3)
效果图:
<template><div @mouseover="mouseover" @mouseout="mouseout"><v-chartref="vChartRef":option="option"style="width: 100%; height: 800px"/></div></template><script setup lang="ts">import { ref, reactive, onMounted, onBeforeUnmount, watch } from "vue";import VChart from "vue-echarts";import { use } from "echarts/core";import { CanvasRenderer } from "echarts/renderers";import { BarChart, PictorialBarChart } from "echarts/charts";import {DatasetComponent,GridComponent,TooltipComponent,LegendComponent,TitleComponent,DataZoomComponent,} from "echarts/components";use([DatasetComponent,CanvasRenderer,BarChart,PictorialBarChart,GridComponent,TooltipComponent,LegendComponent,TitleComponent,DataZoomComponent,]);// 定义数据类型interface ChartDataItem {x: string;y: number;s: string;}// 模拟接口数据数组const chartData = ref<ChartDataItem[]>([{x: "南沙政务",y: 10,s: "测试1",},{x: "珠江街道",y: 20,s: "测试1",},{x: "南沙街道",y: 20,s: "测试1",},{x: "龙穴街道",y: 30,s: "测试1",},{x: "南沙政务",y: 2,s: "测试2",},{x: "珠江街道",y: 4,s: "测试2",},{x: "南沙街道",y: 8,s: "测试2",},{x: "龙穴街道",y: 8,s: "测试2",},]);// 获取图表实例const vChartRef = ref();// 定义不同系列的颜色const seriesColors = ["#029CD4", // 测试1的颜色"#FF6B35", // 测试2的颜色"#6B5B95", // 备用颜色3"#88B77B", // 备用颜色4"#F9A602", // 备用颜色5];// 获取seriesconst seriesItem = ref({type: "pictorialBar",symbolRepeat: true,symbolSize: ["12px", "4px"],symbol: "rect",symbolMargin: 2,itemStyle: {borderRadius: 0,color: "", // 将在getSeries中动态设置},barWidth: 12,name: "",label: {show: false, // 设置为 false 取消柱子上的参数显示fontSize: 12,color: "#000",position: "top",},data: <any>[],});const getSeries = () => {const seriesNames = [...new Set(chartData.value.map((item) => item.s))];const xValues = [...new Set(chartData.value.map((item) => item.x))];const series = seriesNames.map((name, index) => {const seriesItemCopy = JSON.parse(JSON.stringify(seriesItem.value));seriesItemCopy.name = name;// 为每个系列设置不同的颜色const seriesColor = seriesColors[index % seriesColors.length];seriesItemCopy.itemStyle.color = seriesColor;// 初始化数据数组,填充0const seriesData = new Array(xValues.length).fill(0);chartData.value.forEach((item) => {if (item.s === name) {const dataIndex = xValues.indexOf(item.x);if (dataIndex !== -1) {seriesData[dataIndex] = item.y;}}});seriesItemCopy.data = seriesData;return seriesItemCopy;});return { series, xValues };};const option = reactive({grid: {bottom: 60,top: 40,left: 60,right: 20,},legend: {show: true,top: 10,textStyle: {color: "#000",},},xAxis: {show: true,type: "category",data: <any>[],axisLabel: {color: "#000",},axisLine: {lineStyle: {color: "#000",},},},yAxis: {show: true,name: "单位:项",type: "value",axisLabel: {color: "#000",},axisLine: {lineStyle: {color: "#000",},},},tooltip: {trigger: "axis",axisPointer: {type: "shadow",},},series: <any>[],dataZoom: [{type: "inside",start: 0,end: 100,},],});onMounted(() => {const { series, xValues } = getSeries();option.series = series;option.xAxis.data = xValues;setAnimate();});watch(() => option.series,() => {setShowTips();});const isShowTips = ref(true);const timer: any = ref(null);let seriesDataNum = 0;const setShowTips = () => {if (!isShowTips.value && isShowTips.value !== undefined) {clearInterval(timer.value);return;}clearInterval(timer.value);timer.value = setInterval(() => {let series = option.series;let length = series[0].data.length;vChartRef.value?.dispatchAction({type: "showTip",seriesIndex: 0,dataIndex: seriesDataNum,});seriesDataNum = seriesDataNum >= length - 1 ? 0 : seriesDataNum + 1;}, 2000);};const mouseover = () => {if (timer.value) clearInterval(timer.value);if (timechartes.value) clearInterval(timechartes.value);};const mouseout = () => {setShowTips();setAnimate();};onBeforeUnmount(() => {if (timer.value) clearInterval(timer.value);if (timechartes.value) clearInterval(timechartes.value);});const timechartes: any = ref(null);let dataZoom = ref([{xAxisIndex: 0, //这里是从X轴的0刻度开始show: false, //是否显示滑动条,不影响使用type: "inside", // 这个 dataZoom 组件是 slider 型 dataZoom 组件startValue: 0, // 从头开始。endValue: 8, // 一次性展示几个。},]);const setAnimate = () => {if (timechartes.value) clearInterval(timechartes.value);timechartes.value = setInterval(() => {const xValuesLength = [...new Set(chartData.value.map((item) => item.x))].length;// 每次向后滚动一个,最后一个从头开始。if (dataZoom.value[0].endValue === xValuesLength) {dataZoom.value[0].endValue = 8;dataZoom.value[0].startValue = 0;} else {dataZoom.value[0].endValue += 1;dataZoom.value[0].startValue += 1;}}, 2000);};</script>