Ecahrts竖向柱状图实现自动滚动

 效果如下:

1.首先声明一个timer定时器标识

let timer: NodeJS.Timer; // 定时器

2.再声明窗口展示的数量,yAxisIndex2用来记录当前index已经加了多少,方便再formatter中格式化标题的相关信息

const dataZoomEndValue = 6; // 数据窗口范围的结束数值(一次性展示几个)
let yAxisIndex2 = 0; // 表示右侧Y轴从那个刻度开始

3.在option中设置datazoom的相关参数

dataZoom: [
	{
		show: false, // 是否显示滑动条
		yAxisIndex: [0, 1], // // 表示这个 dataZoom 组件控制 第一个 和 二个 yAxis
		startValue: 0, // 数据窗口范围的起始数值
		endValue: dataZoomEndValue // 数据窗口范围的结束数值(一次性展示几个)
	}
],

4.开启一个定时器

getArrByKey(data, "name"):代表的是Y轴标题的数据

getArrByKey(data, "value"):代表的是X轴数量的数据

// 开启定时器自动滚动
if (getArrByKey(data, "name").length > 0 && data.length > 0) {
	timer = setInterval(() => {
		// 每次向后滚动一个,最后一个从头开始
		if (option.dataZoom[0].endValue === getArrByKey(data, "value").length - 1) {
			option.dataZoom[0].startValue = 0; // 数据窗口范围的起始数值
			option.dataZoom[0].endValue = dataZoomEndValue; // 数据窗口范围的结束数值
			yAxisIndex2 = 0;
		} else {
            // 数据窗口范围的起始数值
			option.dataZoom[0].startValue = option.dataZoom[0].startValue + 1; 
            // 数据窗口范围的结束数值
			option.dataZoom[0].endValue = option.dataZoom[0].endValue + 1; 
			yAxisIndex2 += 1;
		}
		myChart.setOption(option);
	}, 2000);
}

5.最后别忘了清除定时器

onUnmounted(() => {
	clearInterval(timer);
});

附上完整代码:

<template>
	<div class="h-220px" style="width: 100%" ref="pieChart"></div>
</template>

<script lang="ts" setup>
import { watch, ref, onMounted, onBeforeUnmount } from "vue";
import * as echarts from "echarts";
import { useEcharts } from "@/hooks/useEcharts";
const pieChart = ref();
const props = defineProps({
	data: {
		type: Object,
		default: () => {}
	}
});
watch(
	() => props.data,
	() => {
		initPieChart();
	},
	{
		deep: true
	}
);
let timer: NodeJS.Timer; // 定时器
const initPieChart = () => {
	// 清除定时器的影响
	if (timer) {
		clearInterval(timer);
	}
	// 判断当前echarts是否存在
	let myChart = echarts.getInstanceByDom(pieChart.value);
	if (myChart == null) {
		myChart = echarts.init(pieChart.value);
	}
	let max = Number(props.data[0]?.stopTime ?? 0); // 假设最大值为数组的第一个元素
	for (let i = 1; i < props.data.length; i++) {
		if (Number(props.data[i].stopTime) > max) {
			// 如果当前元素比最大值大,则更新最大值
			max = props.data[i].stopTime;
		}
	}
	let backData = new Array(props.data.length).fill(max + 1);
	const getArrByKey = (data: any, k: string) => {
		let key = k || "value";
		let res: Array<number> = [];
		if (props.data) {
			props.data.forEach(function (t: any) {
				res.push(t[key]);
			});
		}
		return res;
	};
	const dataZoomEndValue = 6; // 数据窗口范围的结束数值(一次性展示几个)
	let yAxisIndex2 = 0; // 表示右侧Y轴从那个刻度开始

	const option = {
		grid: {
			top: "10%",
			bottom: "-6%",
			right: "2%",
			left: 0,
			containLabel: true
		},
		dataZoom: [
			{
				show: false, // 是否显示滑动条
				yAxisIndex: [0, 1], // // 表示这个 dataZoom 组件控制 第一个 和 二个 yAxis
				startValue: 0, // 数据窗口范围的起始数值
				endValue: dataZoomEndValue // 数据窗口范围的结束数值(一次性展示几个)
			}
		],
		xAxis: {
			show: false
		},
		yAxis: [
			{
				triggerEvent: true,
				show: true,
				inverse: true,
				data: getArrByKey(props.data, "name"),
				axisLine: {
					show: false
				},
				splitLine: {
					show: false
				},
				axisTick: {
					show: false
				},
				axisLabel: {
					interval: 0,
					color: "#8693a4",
					align: "right",
					margin: 18,
					fontSize: 12,
					fontWeight: 400
				}
			},
			{
				name: "时长         占比",
				//name的样式设计
				nameTextStyle: {
					align: "left",
					padding: [-220, 0, 0, 0], //地区名称的位置
					color: "#8693a4",
					fontSize: "12"
				},
				triggerEvent: true,
				show: true,
				inverse: true,
				data: getArrByKey(props.data, "name"),
				axisLine: {
					show: false
				},
				splitLine: {
					show: false
				},
				axisTick: {
					show: false
				},
				axisLabel: {
					interval: 0,
					color: "#8693a4",
					align: "left",
					margin: 0,
					fontSize: 12,
					fontWeight: 400,
					formatter: function (value: any, index: number) {
						// return `<div style="width: 100px; display: flex;justify-content: space-between;align-items: center;"><span>${
						// 	props.data[index + yAxisIndex2].stopTime
						// }</span><span>${props.data[index + yAxisIndex2].stopTimeRatio}%</span></div>`;
						// return props.data[index + yAxisIndex2].stopTime + "     " + props.data[index + yAxisIndex2].stopTimeRatio + "%";
						return (
							"{a|" +
							props.data[index + yAxisIndex2].stopTime +
							"}" +
							"{b|" +
							"     " +
							props.data[index + yAxisIndex2].stopTimeRatio +
							"%" +
							"}"
						);
					},
					rich: {
						a: {
							width: 40
						},
						b: {
							width: 40
						}
					}
				}
			}
		],
		series: [
			{
				name: "条",
				type: "bar",
				yAxisIndex: 0,
				data: props.data.map((item: any) => item.stopTime),
				barWidth: 10,
				itemStyle: {
					color: "#e82461",
					barBorderRadius: [0, 30, 30, 0]
				}
			},
			{
				// For shadow
				type: "bar",
				itemStyle: {
					normal: {
						color: "rgba(255, 255, 255, 0.1)",
						barBorderRadius: [0, 0, 0, 0]
					}
				},
				barWidth: 10,
				barGap: "-100%",
				barCategoryGap: "40%",
				data: backData,
				animation: false,
				yAxisIndex: 1, //使用右侧y轴
				tooltip: {
					show: false
				}
			}
		]
	};

	if (props.data.length > 0 && myChart) {
		useEcharts(myChart, option);
	} else {
		myChart.clear(); //清除图表所有配置项
	}

	// 开启定时器自动滚动
	if (getArrByKey(props.data, "name").length > dataZoomEndValue && props.data.length > dataZoomEndValue) {
		timer = setInterval(() => {
			// 每次向后滚动一个,最后一个从头开始
			if (option.dataZoom[0].endValue === getArrByKey(props.data, "value").length - 1) {
				option.dataZoom[0].startValue = 0; // 数据窗口范围的起始数值
				option.dataZoom[0].endValue = dataZoomEndValue; // 数据窗口范围的结束数值
				yAxisIndex2 = 0;
			} else {
				option.dataZoom[0].startValue = option.dataZoom[0].startValue + 1; // 数据窗口范围的起始数值
				option.dataZoom[0].endValue = option.dataZoom[0].endValue + 1; // 数据窗口范围的结束数值
				yAxisIndex2 += 1;
			}
			myChart?.setOption(option);
		}, 2000);
	}
};
onMounted(() => {
	initPieChart();
});
onBeforeUnmount(() => {
	clearInterval(timer);
});
</script>

<style lang="scss" scoped></style>

  • 13
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值