vue2、vue3分别配置echarts多图表的同步缩放

文章目录

    • ⭐前言
    • ⭐使用dataZoom api实现echart的同步缩放
      • 💖 vue2实现echarts多图表同步缩放
      • 💖 vue3实现echarts多图表同步缩放
    • ⭐结束

⭐前言

大家好!我是yma16,本文分享在vue2和vue3中配置echarts的多图表同步缩放
背景:
解决echarts的多图表x轴同步联动的问题

⭐使用dataZoom api实现echart的同步缩放

echarts的datazoom api对外暴露
echarts-datazoom

原理:
echarts的实例存在datazoom缩放的方法,
所以只需要在datazoom事件触发其他图表的datazoom即可实现同步缩放

dispatchAction({type: 'dataZoom',// 可选,dataZoom 组件的 index,多个 dataZoom 组件时有用,默认为 0dataZoomIndex: number,// 开始位置的百分比,0 - 100start: number,// 结束位置的百分比,0 - 100end: number,// 开始位置的数值startValue: number,// 结束位置的数值endValue: number
})

注意:
x轴的范围要一致,不然可能会出现偏移

💖 vue2实现echarts多图表同步缩放

用变量记录echarts的实例,渲染完毕再触发datazoom

<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>echarts 滚动事件</title><!-- vue2 生产环境版本,优化了尺寸和速度 --><script src="https://cdn.jsdelivr.net/npm/vue@2"></script><script src="./echarts.js"></script></head><style>#app {position: absolute;height: 100vh;width: 100vw;}</style><body><div id="app"><div>first<div id="first" style="width: 900px;height:400px;"></div>second<div id="second" style="width: 900px;height:400px;"></div>third<div id="third" style="width: 900px;height:400px;"></div></div></div><script type="text/javascript">const instanceVue = {el: '#app',name: 'ecahrts',data() {return {firstChart: null,secondChart: null,thirdChart: null,maxNum:1000,};},mounted() {this.initSecondData()this.initThirdData()this.initFirstData()},methods: {initFirstData() {// 基于准备好的dom,初始化echarts实例var myChart = echarts.init(document.getElementById('first'));// 指定图表的配置项和数据let base = +new Date(1968, 9, 3);let oneDay = 24 * 3600 * 500;let date = [];let data = [Math.random() * 300];for (let i = 1; i < this.maxNum; i++) {var now = new Date((base += oneDay));date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));}const option = {tooltip: {trigger: 'axis',position: function(pt) {return [pt[0], '10%'];}},title: {left: 'center',text: 'Large Area Chart'},toolbox: {feature: {dataZoom: {yAxisIndex: 'none'},restore: {},saveAsImage: {}}},xAxis: {type: 'category',boundaryGap: false,data: date},yAxis: {type: 'value',boundaryGap: [0, '100%']},dataZoom: [{type: 'inside',start: 0,end: 10},{start: 0,end: 10}],series: [{name: 'Fake Data',type: 'bar',symbol: 'none',sampling: 'lttb',itemStyle: {color: 'rgb(255, 70, 131)'},areaStyle: {color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [{offset: 0,color: 'rgb(255, 158, 68)'},{offset: 1,color: 'rgb(255, 70, 131)'}])},data: data}]};// 使用刚指定的配置项和数据显示图表。myChart.setOption(option);// 监听this.firstChart = myChart;this.asyncZoom()},asyncZoom() {const that = thisthis.firstChart.on('datazoom', function(params) {[that.secondChart, that.thirdChart].forEach(item => {console.log('item',item)item && item.dispatchAction({ // 触发 dataZoom 事件type: 'dataZoom',zoomLock: true, // 锁定整个图表的缩放功能xAxisIndex: params.xAxisIndex, // xAxisIndex 为当前操作的 xAxisIndex,用于确定对应的 xAxis 对象yAxisIndex: params.yAxisIndex, // yAxisIndex 为当前操作的 yAxisIndex,用于确定对应的 yAxis 对象start: params.start, // start 为当前操作的时间范围起始值end: params.end // end 为当前操作的时间范围结束值});})})},initSecondData() {// 基于准备好的dom,初始化echarts实例const myChart = echarts.init(document.getElementById('second'));// 指定图表的配置项和数据let base = +new Date(1968, 9, 3);let oneDay = 24 * 3600 * 500;const date = []const yData1 = [Math.random() * 300]const yData2 = [Math.random() * 100]for (let i = 1; i < this.maxNum; i++) {var now = new Date((base += oneDay));date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'))yData1.push(Math.round((Math.random() - 0.5) * 20 + yData1[i - 1]));yData2.push(Math.round((Math.random() - 0.5) * 20 + yData2[i - 1]));}const option = {title: {text: 'line'},tooltip: {trigger: 'axis'},legend: {},toolbox: {show: true,feature: {dataZoom: {yAxisIndex: 'none'},dataView: {readOnly: false},magicType: {type: ['line', 'bar']},restore: {},saveAsImage: {}}},xAxis: {type: 'category',boundaryGap: false,data: date},yAxis: {type: 'value',axisLabel: {formatter: '{value} °C'}},series: [{name: 'Highest',type: 'line',data: yData1,markPoint: {data: [{type: 'max',name: 'Max'},{type: 'min',name: 'Min'}]},markLine: {data: [{type: 'average',name: 'Avg'}]}},{name: 'Lowest',type: 'line',data: yData2,markPoint: {data: [{name: '周最低',value: -2,xAxis: 1,yAxis: -1.5}]},markLine: {data: [{type: 'average',name: 'Avg'},[{symbol: 'none',x: '90%',yAxis: 'max'},{symbol: 'circle',label: {position: 'start',formatter: 'Max'},type: 'max',name: '最高点'}]]}}]};myChart.setOption(option);this.secondChart = myChart;},initThirdData() {// 基于准备好的dom,初始化echarts实例const myChart = echarts.init(document.getElementById('third'));// 指定图表的配置项和数据let base = +new Date(1968, 9, 3);let oneDay = 24 * 3600 * 500;const date = []const yData1 = [Math.random() * 300]for (let i = 1; i < this.maxNum; i++) {var now = new Date((base += oneDay));date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'))yData1.push(Math.round((Math.random() - 0.5) * 20 + yData1[i - 1]));}option = {toolbox: {show: true,feature: {dataZoom: {yAxisIndex: 'none'},dataView: {readOnly: false},magicType: {type: ['line', 'bar']},restore: {},saveAsImage: {}}},tooltip:{trigger:'axis'},legend: {},grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true},xAxis: [{type: 'category',boundaryGap: false,data: date}],yAxis: [{type: 'value',}],series: [{name: 'Direct',type: 'bar',data: yData1}]};myChart.setOption(option);this.thirdChart = myChart;}}}// 实例化new Vue(instanceVue);</script></body>
</html>

代码在insidecode,如下运行即可


效果:
vue2-datazoom-chart

💖 vue3实现echarts多图表同步缩放

用state存储echarts实例,渲染完之后触发dataZoom

<template><div><!--    折线图--><div id="first" :style="{ width, height }"></div><!--    柱状图--><div id="second" :style="{ width, height }"></div><div id="third" :style="{ width, height }"></div><div id="fourth" :style="{ width, height }"></div></div>
</template>
<script lang="ts" setup>import {  reactive, onMounted } from 'vue';import * as echarts from 'echarts';const state: any = reactive({maxNum: 100,// 折线图lineChart1: null,// 柱状图1barChart1: null,// 柱状图2barChart2: null,// 柱状图3barChart3: null,});function asyncZoom() {console.log(' state.lineChart1', state.lineChart1);state?.lineChart1?.on('datazoom', function (params) {[state.barChart1, state.barChart2, state.barChart2, state.barChart3].forEach((item) => {console.log('item', item);item &&item.dispatchAction({// 触发 dataZoom 事件type: 'dataZoom',zoomLock: true, // 锁定整个图表的缩放功能xAxisIndex: params.xAxisIndex, // xAxisIndex 为当前操作的 xAxisIndex,用于确定对应的 xAxis 对象yAxisIndex: params.yAxisIndex, // yAxisIndex 为当前操作的 yAxisIndex,用于确定对应的 yAxis 对象start: params.start, // start 为当前操作的时间范围起始值end: params.end, // end 为当前操作的时间范围结束值});});});}function renderLineChart4(val: any): any {// const { setOptions } = useECharts(chartLineRef1 as Ref<HTMLDivElement>);const myChart = echarts.init(document.getElementById('fourth'));if (!myChart) {return;}// 指定图表的配置项和数据let base = +new Date(1968, 9, 3);let oneDay = 24 * 3600 * 500;const date = [];const yData1 = [Math.random() * 300];for (let i = 1; i < state.maxNum; i++) {var now = new Date((base += oneDay));date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));yData1.push(Math.round((Math.random() - 0.5) * 20 + yData1[i - 1]));}const option = {toolbox: {show: true,feature: {dataZoom: {yAxisIndex: 'none',},dataView: {readOnly: false,},magicType: {type: ['line', 'bar'],},restore: {},saveAsImage: {},},},legend: {},grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true,},xAxis: [{type: 'category',boundaryGap: false,data: date,},],yAxis: [{type: 'value',},],series: [{name: 'Direct',type: 'bar',data: yData1,},],};console.log('option', option);myChart.setOption(option, true);// dom.setOption(option, true);state.barChart3 = myChart;}function renderLineChart3(val: any): any {// const { setOptions } = useECharts(chartLineRef1 as Ref<HTMLDivElement>);const myChart = echarts.init(document.getElementById('third'));if (!myChart) {return;}// 指定图表的配置项和数据let base = +new Date(1968, 9, 3);let oneDay = 24 * 3600 * 500;const date = [];const yData1 = [Math.random() * 300];for (let i = 1; i < state.maxNum; i++) {var now = new Date((base += oneDay));date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));yData1.push(Math.round((Math.random() - 0.5) * 20 + yData1[i - 1]));}const option = {toolbox: {show: true,feature: {dataZoom: {yAxisIndex: 'none',},dataView: {readOnly: false,},magicType: {type: ['line', 'bar'],},restore: {},saveAsImage: {},},},legend: {},grid: {left: '3%',right: '4%',bottom: '3%',containLabel: true,},xAxis: [{type: 'category',boundaryGap: false,data: date,},],yAxis: [{type: 'value',},],series: [{name: 'Direct',type: 'bar',data: yData1,},],};console.log('option', option);myChart.setOption(option, true);// dom.setOption(option, true);state.barChart2 = myChart;}function renderLineChart2(val: any): any {// const { setOptions } = useECharts(chartLineRef1 as Ref<HTMLDivElement>);const myChart = echarts.init(document.getElementById('second'));if (!myChart) {return;}let base = +new Date(1968, 9, 3);let oneDay = 24 * 3600 * 500;const date = [];const yData1 = [Math.random() * 300];const yData2 = [Math.random() * 100];for (let i = 1; i < state.maxNum; i++) {var now = new Date((base += oneDay));date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));yData1.push(Math.round((Math.random() - 0.5) * 20 + yData1[i - 1]));yData2.push(Math.round((Math.random() - 0.5) * 20 + yData2[i - 1]));}const option = {title: {text: 'line',},tooltip: {trigger: 'axis',},legend: {},toolbox: {show: true,feature: {dataZoom: {yAxisIndex: 'none',},dataView: {readOnly: false,},magicType: {type: ['line', 'bar'],},restore: {},saveAsImage: {},},},xAxis: {type: 'category',boundaryGap: false,data: date,},yAxis: {type: 'value',axisLabel: {formatter: '{value} °C',},},series: [{name: 'Highest',type: 'line',data: yData1,markPoint: {data: [{type: 'max',name: 'Max',},{type: 'min',name: 'Min',},],},markLine: {data: [{type: 'average',name: 'Avg',},],},},{name: 'Lowest',type: 'line',data: yData2,markPoint: {data: [{name: '周最低',value: -2,xAxis: 1,yAxis: -1.5,},],},markLine: {data: [{type: 'average',name: 'Avg',},[{symbol: 'none',x: '90%',yAxis: 'max',},{symbol: 'circle',label: {position: 'start',formatter: 'Max',},type: 'max',name: '最高点',},],],},},],};console.log('option', option);myChart.setOption(option, true);// dom.setOption(option, true);state.barChart1 = myChart;}function renderLineChart1(val: any): any {// const { setOptions } = useECharts(chartLineRef1 as Ref<HTMLDivElement>);const myChart = echarts.init(document.getElementById('first'));if (!myChart) {return;}// 指定图表的配置项和数据let base = +new Date(1968, 9, 3);let oneDay = 24 * 3600 * 500;let date = [];let data = [Math.random() * 300];for (let i = 1; i < state.maxNum; i++) {var now = new Date((base += oneDay));date.push([now.getFullYear(), now.getMonth() + 1, now.getDate()].join('/'));data.push(Math.round((Math.random() - 0.5) * 20 + data[i - 1]));}const option = {tooltip: {trigger: 'axis',position: function (pt) {return [pt[0], '10%'];},},title: {left: 'center',text: 'Large Area Chart',},toolbox: {feature: {dataZoom: {yAxisIndex: 'none',},restore: {},saveAsImage: {},},},xAxis: {type: 'category',boundaryGap: false,data: date,},yAxis: {type: 'value',boundaryGap: [0, '100%'],},dataZoom: [{type: 'inside',start: 0,end: 10,},{start: 0,end: 10,},],series: [{name: 'Fake Data',type: 'bar',symbol: 'none',sampling: 'lttb',itemStyle: {color: 'rgb(255, 70, 131)',},data: data,},],};console.log('option', option);myChart.setOption(option, true);state.lineChart1 = myChart;asyncZoom();}onMounted(() => {renderLineChart4();renderLineChart3();renderLineChart2();renderLineChart1();});
</script>

效果
vue3-dataZoom

⭐结束

本文分享结束, 💖 感谢你的阅读💖
如有不足或者错误欢迎指出!
scene-line-sky

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/4061.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

vscode关闭调试工具栏

问题描述 项目启动的时候老是蹦出这玩意 很碍眼 解决方案&#xff1a; 设置里搜索 选项改为hidden即可

The Company Requires Superficial StudyPHP 变量的使用 ③

作者 : SYFStrive 博客首页 : HomePage &#x1f4dc;&#xff1a; PHP MYSQL &#x1f4cc;&#xff1a;个人社区&#xff08;欢迎大佬们加入&#xff09; &#x1f449;&#xff1a;社区链接&#x1f517; &#x1f4cc;&#xff1a;觉得文章不错可以点点关注 &#x1f44…

基于matlab使用形态操作对视频流中的对象进行计数(附源码)

一、前言 此示例演示如何使用形态操作对视频流中的对象进行计数 输入视频流包含订书钉的图像。在此示例中&#xff0c;您使用平顶形态操作来消除不均匀的照明&#xff0c;并使用打开形态操作来消除订书钉之间的间隙。然后&#xff0c;将图像转换为二进制&#xff0c;对每个帧…

【Spring Boot 】Spring Boot 统一功能处理

&#x1f389;&#x1f389;&#x1f389;点进来你就是我的人了博主主页&#xff1a;&#x1f648;&#x1f648;&#x1f648;戳一戳,欢迎大佬指点! 欢迎志同道合的朋友一起加油喔&#x1f93a;&#x1f93a;&#x1f93a; 目录 前言 1. Spring 拦截器 1.1 自定义拦截器 1…

卷积神经网络--猫狗系列之构建模型【ResNet50】

在上一期&#xff1a;卷积神经网络--猫狗系列之下载、导入数据集&#xff0c;如果测试成功就说明对数据的预处理工作已经完成&#xff0c;接下来就是构建模型阶段了&#xff1a; 据说建立一个神经网络模型比较简单&#xff0c;只要了解了各层的含义、不同层之间参数的传递等等&…

【Thunder送书 | 第三期 】「Python系列丛书」

文章目录 前言《Python高效编程——基于Rust语言》《Python从入门到精通》《Python Web深度学习》《Python分布式机器学习》文末福利 | 赠书活动 前言 Thunder送书第三期开始啦&#xff01;前面两期都是以【文末送书】的形式开展&#xff0c;本期将赠送Python系列丛书&#xff…

html_css模拟端午赛龙舟运动

文章目录 ⭐前言&#x1f496; 样式布局&#x1f496; 添加龙舟&#x1f496; 添加css_animation运动 ⭐结束 ⭐前言 大家好&#xff0c;我是yma16&#xff0c;本期给大家分享css实现赛龙舟运动。 &#x1f496; 样式布局 风格&#xff1a;卡通 首先采用一张包括水元素的照片…

docker安装rabbitMQ,JAVA连接进行生产和消费,压测

1.docker安装 docker安装以及部署_docker bu shuminio_春风与麋鹿的博客-CSDN博客 2.doker安装rabbitMQ 使用此命令获取镜像列表 docker search rabbitMq 使用此命令拉取镜像 docker pull docker.io/rabbitmq:3.8-management 这里要注意&#xff0c;默认rabbitmq镜像是…

【MySQL】表的操作

目录 一、创建表 1、创建规则 2、创建案例 二、查看表结构 三、修改表 1、更改表名 2、 向表中插入数据 3、在表中添加字段 4、修改字段属性 5、从表中删除字段 6、修改字段名字 四、删除表 一、创建表 1、创建规则 CREATE TABLE table_name (field1 datatype,fi…

【C++】C++关于异常的学习

文章目录 C语言传统的处理错误的方式一、异常的概念及用法二、自定义异常体系总结 C语言传统的处理错误的方式 传统的错误处理机制&#xff1a; 1. 终止程序&#xff0c;如 assert &#xff0c;缺陷&#xff1a;用户难以接受。如发生内存错误&#xff0c;除 0 错误时就会终止…

PyQt中数据库的访问(一)

访问数据库的第一步是确保ODBC数据源配置成功&#xff0c;我接下来会写数据源配置的文章&#xff0c;请继续关注本栏&#xff01; &#xff08;一&#xff09;数据库连接 self.DBQSqlDatabase.addDatabase("QODBC") self.DB.setDatabaseName("Driver{sqlServer…

chatGPT AI对话聊天绘画系统开发:打开人工智能AI社交聊天系统开发新时代

人工智能技术的快速发展和普及&#xff0c;催生了众多创新应用&#xff0c;其中&#xff0c;AI社交聊天系统成为当下市场的热门话题&#xff0c;本文将详细介绍开发属于自己的ChatGPT的过程&#xff0c;并探讨当下市场因Chat AI聊天系统所带来的影响性。 AI社交聊天系统的潜力与…