当前位置: 首页 > news >正文

echarts 多toolti同时触发图表实现

  • 需求背景
  • 解决效果
  • ISQQW代码地址
  • energyChart.vue

需求背景

需要实现同x轴,4个图表的的多图表联动效果,且滑动会触发各个图表的tooltip,即一个图表拥有4个tooltip(目前echarts不支持,我这里绕过了这个问题)

解决效果

ISQQW代码地址

由于ISQQW只能上传一个option对象的图表,故未上传

energyChart.vue

<!--/**
* @author: liuk
* @date: 2023/11/21
* @describe: 能耗分析图表
* @email:https://blog.csdn.net/hr_beginner?spm=1018.2226.3001.5343
*/-->
<template><div ref="chatDom1" class="energyChart"></div><div ref="chatDom2" class="energyChart"></div><div ref="chatDom3" class="energyChart"></div><div ref="chatDom4" class="energyChart"></div>
</template><script lang="ts" setup>
import {ref, onMounted, watch, nextTick} from "vue"
import * as echarts from 'echarts'
import {formatToFixed} from "@/utils/dictionary";// Props
const props = defineProps(['data'])
const myCharts = {// Vue3 使用 proxy 对象代理,而 echarts 则使用了大量的全等(===), 对比失败从而导致了bug。myChart1: null,myChart2: null,myChart3: null,myChart4: null
}const chatDom1 = ref(null)
const chatDom2 = ref(null)
const chatDom3 = ref(null)
const chatDom4 = ref(null)watch(() => props.data, (data) => {nextTick(() => {renderFn(myCharts.myChart1, {xData: data.heatRateHistory.map(item => item.time),yName: '度日数单耗 W/m²·℃',sData: data.heatRateHistory.map(item => formatToFixed(item.heatRate)),markLineVal: data.heatRateHistory[0]?.heatRate3 || 0,color: '#EB8F4A'})renderFn(myCharts.myChart2, {xData: data.flowPowerHistory.map(item => item.time),yName: '电单耗 W/m²',sData: data.flowPowerHistory.map(item => formatToFixed(item.power1)),markLineVal: data.flowPowerHistory[0]?.power3 || 0,color: '#BF97FF'})renderFn(myCharts.myChart3, {xData: data.flowPowerHistory.map(item => item.time),yName: '水单耗 W/m²',sData: data.flowPowerHistory.map(item => formatToFixed(item.flow1)),markLineVal: data.flowPowerHistory[0]?.flow3 || 0,color: "#5690FF"})renderFn(myCharts.myChart4, {xData: data.energyAnalysisData.time,yName: '室外温度 °C',sData: data.energyAnalysisData.tt301_value_val_arr,markLineVal: false,color: '#00CCA3'})})
})onMounted(() => {drawChart(chatDom1.value, 1)drawChart(chatDom2.value, 2)drawChart(chatDom3.value, 3)drawChart(chatDom4.value, 4)echarts.connect('sameControls'); // **相同操作window.addEventListener('resize', () => {renderFn(myCharts.myChart1, {xData: props.data.heatRateHistory.map(item => item.time),yName: '度日数单耗 W/m²·℃',sData: props.data.heatRateHistory.map(item => formatToFixed(item.heatRate)),markLineVal: props.data.heatRateHistory[0]?.heatRate3 || 0,color: '#EB8F4A'})renderFn(myCharts.myChart2, {xData: props.data.flowPowerHistory.map(item => item.time),yName: '电单耗 W/m²',sData: props.data.flowPowerHistory.map(item => formatToFixed(item.power1)),markLineVal: props.data.flowPowerHistory[0]?.power3 || 0,color: '#BF97FF'})renderFn(myCharts.myChart3, {xData: props.data.flowPowerHistory.map(item => item.time),yName: '水单耗 W/m²',sData: props.data.flowPowerHistory.map(item => formatToFixed(item.flow1)),markLineVal: props.data.flowPowerHistory[0]?.flow3 || 0,color: "#5690FF"})renderFn(myCharts.myChart4, {xData: props.data.energyAnalysisData.time,yName: '室外温度 °C',sData: props.data.energyAnalysisData.tt301_value_val_arr,markLineVal: false,color: '#00CCA3'})}, {passive: true});
})const renderFn = (myChart, {xData, yName, sData, markLineVal, color}) => {const option = myChart.getOption()option.xAxis[0].data = xDataoption.xAxis[0].min = nulloption.yAxis[0].name = yNameoption.series[0].name = yNameoption.series[0].data = sDataoption.series[0].color = coloroption.series[0].markLine.data[0].yAxis = markLineValoption.series[0].markLine.data[0].label.color = colorif (markLineVal === false) delete option.series[0].markLineoption.tooltip[0].formatter = (param) => {const data = param[0] || {}const temp = data.data - markLineValconst [name, unit] = yName.split(" ")const nameArr = [{name,num: data.data},{name: '基准年' + name,num: markLineVal},{name: '对比基准年',num: temp}]return `${nameArr.map((item, i) => {return `<p class="energyChart-item"><i class="icon" style="color:${i === 3 ? '#fff' : data.color}">${new Array(1).fill('').map(() => {switch (i) {case 0:return '一'case 1:return '···'case 2:return temp > 0 ? '↑' : '↓'}})[0]}</i><span class="name">${item.name}</span><span>${formatToFixed(item.num)}</span><span>${unit}</span></p>`}).join("")}`}myChart.clear()myChart.setOption(option)
}const drawChart = (chatDom, n) => {let chartDom = chatDomif (chartDom == null) {return}echarts.dispose(chartDom)myCharts['myChart' + n] = echarts.init(chartDom)myCharts['myChart' + n].group = 'sameControls';const option = {grid: [{top: 29,left: 90,right: 90,height: 100},],axisPointer: {type: 'shadow',link: {xAxisIndex: 'all'},},tooltip: {trigger: 'axis',backgroundColor: 'rgba(61,57,48,0.8)',borderColor: 'rgba(149,149,149,0.8)',textStyle: {color: '#fff'},},xAxis: [{data: ['08:00', '09:00', '10:00', '11:00', '12:00', '13:00', '14:00', '15:00', '16:00', '17:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00', '00:00', '01:00', '02:00', '03:00', '04:00', '05:00', '06:00', '07:00', '08:00'],boundaryGap: false,axisLine: {show: true,onZero: false,},min: 'dataMin',axisTick: {show: true,alignWithLabel: true,},axisLabel: {show: true,color: 'rgba(165,166,166,1)',fontSize: '12',},}],yAxis: [{name: '度日数单耗 W/m²·℃',offset: 20,nameTextStyle: {padding: [0, 0, 0, -10],color: '#fff',fontSize: '14',opacity: 0.7,align: 'left',fontWeight: 'normal'},nameLocation: 'end',position: 'left',axisTick: {show: false},splitLine: {show: true,lineStyle: {type: 'dashed',color: 'rgba(52,52,52,1)'}},axisLine: {show: false,},axisLabel: {show: true,align: 'left',showMinLabel: false,color: 'rgba(165,166,166,1)',fontSize: '14',formatter: (val) => {switch (true) {case val < 1000:return valcase val >= 1e3 && val < 1e4:return (val / 1e3).toFixed(1) + 'k'default:return (val / 1e4).toFixed(1) + 'w'}}},},],series: [{name: '度日数单耗',type: 'line',symbol: 'image://',data: [-1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, -12, 13, 14, 15, 16, 17, 18, 19, -20, 21, 22, -23, 24],markLine: {symbol: "none",silent: true,data: [{yAxis: 5,label: {show: true,position: 'start',color: 'rgba(238,145,75,1)',}}]},lineStyle: {type: 'solid'}},]}option && myCharts['myChart' + n].setOption(option)
}
</script><style lang="scss" scoped>
.energyChart {width: 100%;height: 175px;margin-top: 5px;
}
</style>
<style lang="scss">
.energyChart-item {display: flex;align-items: center;margin: 10px 0;&:last-child {margin-bottom: 0;}.icon {display: inline-block;width: 12px;text-align: center;margin-right: 10px;}.name {display: inline-block;width: 120px;margin-right: 20px;}
}
</style>

相关文章:

  • 数理统计的基本概念(二)
  • 操作系统安装在哪里?
  • Spark 平障录
  • YOLO目标检测——无人机检测数据集下载分享【含对应voc、coco和yolo三种格式标签】
  • Android studio Build Log乱码+错误: 找不到符号符号
  • QT在线安装指南
  • Mysql查看Binlog文件
  • 手机运行内存大揭秘:探索你手机的超级大脑!
  • 《Deep learning for fine-grained image analysis: A survey》阅读笔记
  • vscode 创建 运行c++ 项目
  • 2022最新版-李宏毅机器学习深度学习课程-P49 GPT的野望
  • 【算法-字符串1】反转字符串 + 反转字符串2
  • 关于在x64系统下使用MSSQL导入导出工具读取Excel报错的一个坑
  • 掌握 AI 和 NLP:深入研究 Python — 情感分析、NER 等
  • EtherCAT 伺服控制功能块实现
  • 【React系列】如何构建React应用程序
  • 【笔记】你不知道的JS读书笔记——Promise
  • chrome扩展demo1-小时钟
  • EOS是什么
  • mongo索引构建
  • springboot_database项目介绍
  • V4L2视频输入框架概述
  • 得到一个数组中任意X个元素的所有组合 即C(n,m)
  • 发布国内首个无服务器容器服务,运维效率从未如此高效
  • 分类模型——Logistics Regression
  • 面试遇到的一些题
  • 悄悄地说一个bug
  • 微信公众号开发小记——5.python微信红包
  • 我建了一个叫Hello World的项目
  • 小程序滚动组件,左边导航栏与右边内容联动效果实现
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • ​ 无限可能性的探索:Amazon Lightsail轻量应用服务器引领数字化时代创新发展
  • ​ArcGIS Pro 如何批量删除字段
  • $(function(){})与(function($){....})(jQuery)的区别
  • (09)Hive——CTE 公共表达式
  • (6)设计一个TimeMap
  • (MIT博士)林达华老师-概率模型与计算机视觉”
  • (八)Spring源码解析:Spring MVC
  • (附源码)spring boot火车票售卖系统 毕业设计 211004
  • (介绍与使用)物联网NodeMCUESP8266(ESP-12F)连接新版onenet mqtt协议实现上传数据(温湿度)和下发指令(控制LED灯)
  • (六)激光线扫描-三维重建
  • (转)菜鸟学数据库(三)——存储过程
  • ./configure,make,make install的作用
  • .net 获取url的方法
  • .NET 中的轻量级线程安全
  • .NET/C# 判断某个类是否是泛型类型或泛型接口的子类型
  • .NET/C# 在代码中测量代码执行耗时的建议(比较系统性能计数器和系统时间)...
  • .netcore 获取appsettings
  • .NET学习全景图
  • :如何用SQL脚本保存存储过程返回的结果集
  • [AutoSar]BSW_OS 01 priority ceiling protocol(PCP)
  • [C++]C++基础知识概述
  • [C++]拼图游戏
  • [C++提高编程](三):STL初识
  • [github配置] 远程访问仓库以及问题解决