ehcarts 实战小计-1
需求
- 展示未来未来36个月(等分为3个时间范围)的经济效益趋势,3个等分时间区域在趋势图上方常显,不同时间区域之间通过灰色虚线间隔开;
- 鼠标hover趋势图每个1/3区域,对应区域会有以下3个效果:
- 时间范围卡片高亮;
- 趋势图上方展示对应指标;
- 趋势图展示阴影效果;
- 鼠标hover or 点击趋势图无tooltips
实现方案
将整个需求拆分为三部分:
常态数据展示
数据来源中包含两组数据:baseData
与data
,分别为图中底部的蓝线与顶部的灰线;阴影区域展示的为两部分的差值diffData
;
常态显示可通过baseData
与diffData
设置相同值的stack
,即可产生堆叠的效果:
查看代码
const diffData = baseData.map((_,index) => (data[index] - baseData[index]));
// echarts options
const options = {
// other options
// ...
series: [
{
name: 'data',
type: 'line',
lineStyle: {
width: 1.5,
color: 'rgba(0, 0, 0, 0.1)'
},
showSymbol: false,
data: data,
markLine: {
symbol: 'none',
silent: true,
lineStyle: {
color: 'rgba(0, 0, 0, 0.1)',
type: 'solid',
width: 1
},
data: [
{
xAxis: xData[11],
name: 'first period',
label: {
show: false
}
},
{
xAxis: xData[23],
name: 'second period',
label: {
show: false
}
},
{
xAxis: xData[35],
name: 'third period',
label: {
show: false
}
}
]
}
},
{
name: 'baseData',
type: 'line',
stack: 'total',
lineStyle: {
width: 1.5,
color: '#4476FF'
},
showSymbol: false,
data: baseData
}
]
};
等分时间区
等分时间去分为两部分:图中的灰线与顶部的时间区名称;
本方案中灰线采用markLine
,而顶部的时间区有hover逻辑的展示,所以采用外层覆盖遮罩的方式实现:
hover逻辑
hover时需要改变对应时间区内数据的areaStyle,并且展示由此计算的另一个数据 calculatedData
,所以将这部分逻辑放在遮罩层中展示,根据hover拿到对应的时间区ID再执行相应的计算:
- 定义echarts实例的
hover
事件,获取对应的hoverIndex
- 根据
hoverIndex
将diffData
截断为hoverData
与unHoverData
,并更新options
的series
- 根据
hoverIndex
选取对应时间区的数据计算calculatedData
- 根据
hoverIndex
渲染时间区高亮和calculatedData
展示
实现中遇到的问题
- 图像在hover时出现闪烁
- hover时机只在hover到数据点上才触发,需求需要在对应时间区
- 区域采用图片填充
本文采用的是echarts-for-react
组件库:
hover的逻辑初步通过定义ReactEcharts的onEvents
属性定义
const onEvents = {
'hoverover': handleHover,
}
...
<ReactECharts
option={options}
onEvents={onEvents}
/>
问题1原因:charts在组件内部重新渲染图表去绑定事件
解决方案:采用 onChartReady
回调绑定事件
import React, { useEffect, useRef } from 'react';
import ReactECharts from 'echarts-for-react';
const MyChartComponent = () => {
// 创建一个 ref 来引用 ECharts 实例
const chartRef = useRef(null);
// 使用 useEffect 来处理组件加载和卸载的逻辑
useEffect(() => {
// 定义一个回调函数,用于在图表准备好后执行
const onChartReadyCallback = (chart) => {
// 这里可以获取 ECharts 实例并进行操作
// 例如,绑定 click 事件
chart.on('click', (params) => {
console.log('Chart clicked', params);
});
// 你还可以在这里执行其他操作,比如设置特定的配置项等
};
// 如果 chartRef 当前有当前的 ECharts 实例,就调用回调函数
if (chartRef.current) {
onChartReadyCallback(chartRef.current.getEchartsInstance());
}
// 组件卸载时,注销事件监听器
return () => {
const chart = chartRef.current.getEchartsInstance();
if (chart) {
chart.off('click');
}
};
}, []);
// 定义图表的配置项
const getOption = () => {
return {
title: {
text: 'ECharts Example'
},
tooltip: {},
legend: {
data:['Sales']
},
xAxis: {
data: ["shirt", "cardigan", "chiffon shirt", "pants", "heels", "socks"]
},
yAxis: {},
series: [{
name: 'Sales',
type: 'bar',
data: [5, 20, 36, 10, 10, 20]
}]
};
};
return (
<ReactECharts
ref={chartRef}
option={getOption()}
style={{ height: 400 }}
onChartReady={onChartReadyCallback}
/>
);
};
export default MyChartComponent;
问题2:本文的数据量较少,考虑实现hover对应区域而不是数据点,采用tooltip
的formatter
替代开始的hover逻辑
const options = {
tooltip: {
trigger: 'axis',
transitionDuration: 0,
formatter: renderToolTip,
}
}
const renderToolTip = (params) => {
const hoverdIndex = Math.floor(params[0]?.dataIndex / 12);
// other hover operation...
}
问题3:echarts的区域可以采用图片填充,需要注意的是图片引入的路径问题
React中引入静态资源都是使用相对路径引入,地址是基于入口文件index.html的而不是当前js文件的,以本次要实现的阴影区域填充为例
areaStyle: {
color: { image: '../assets/imgs/fill-img.svg', repeat: 'repeat' }
}
此种方式的src是固定的字符串,当进行webpack打包时可能会出现路径问题,不推荐
正确方式是使用import
引入,如
import fillSVG from '../assets/imgs/fill-img.svg';
//...
const options = {
// other options
areaStyle: {
color: { image: fillSVG, repeat: 'repeat' }
},
}
这里导入的fillSVG
是动态导入的,具有动态路径,且是基于Webpack编译后的文件的,因此推荐这种方式。
最终效果
ehcarts 实战小计-1的更多相关文章
- SQLSERVER 使用 ROLLUP 汇总数据,实现分组统计,合计,小计
表结构: CREATE TABLE [dbo].[Students]( ,) NOT NULL, ) NULL, [Sex] [int] NOT NULL, ) NULL, ) NULL, , ) N ...
- PB gird类型数据窗口 设置分组、分组小计、合计
今天遇到一个需求,gird表格数据如下: 部门 类型 数据 A 类型1 1 A 类型2 2 B 类型1 3 B 类型2 4 合计 10 实际需要显示的结果为: 部门 ...
- 简单的angular购物车商品小计
<!DOCTYPE html> <html lang="en" ng-app="shopApp"> <head> <m ...
- C#给DataTable添加序号、C#给DataTable添加合计、小计
/// <summary> /// 给DataTable添加序号 /// </summary> /// <param name= ...
- SAP ALV中同一列的不同行显示不同的小数位,并能够总计,小计
物料数量字段,根据物料类型的不同,来显示不同的小数位:要求有点苛刻: 首先,要能够总计和小计的话,这一列的字段类型必须是数值类型. 这样的话,就不能通过截取的方式改变不同行的小数位. 以下是两种思路: ...
- 每日学习心得:SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析)
2013-8-20 1. SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析) 在实际的项目开发中有很多项目都会有报表模块,今天就通过一个小的SQL ...
- VMProtect使用小计【一】
文章列表 VMProtect使用小计[一] – 初次使用VMProtect使用小计[二] – 加壳查看VMProtect使用小计[三] – 权限管理 说明 VMProtect的功能我就不说了,详情大家 ...
- 用SQL实现统计报表中的"小计"与"合计"的方法详解
本篇文章是对使用SQL实现统计报表中的"小计"与"合计"的方法进行了详细的分析介绍,需要的朋友参考下 客户提出需求,针对某一列分组加上小计,合计汇总.网上找 ...
- 【IOS实例小计】今日开贴,记录我的ios学习生涯,留下点滴,留下快乐,成荫后人。
今天开贴来记录自己的ios学习过程,本人目前小白一个,由于对ios感兴趣,所以开始学习,原职java程序,呵呵,勿喷. 本次的[ios实例小计]主要参考一文http://blog.sina.com.c ...
- SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析)
SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析) 2013-8-20 1. SQL查询表的行列转换/小计/统计(with rollup,with ...
随机推荐
- CoST: 时间序列预测中分离季节趋势特征的对比学习《CoST: CONTRASTIVE LEARNING OF DISENTANGLED SEASONAL-TREND REPRESENTATIONS FOR TIME SERIES FORECASTING》(时序预测、表征学习、对比学习、因果关系、分离趋势季节特征)
2022/6/18 11:32,简单记录一下随笔(因为不写点东西,根本注意力不集中,看5分钟可能要摸鱼10分钟,还是要写点,突然发现,草稿箱里最早的一篇没写完的博客是去年的7月2日,救命啊,我拖了一年 ...
- vue3 3.3.4
https://cn.vuejs.org/guide/introduction.html#what-is-vue 简介 import { createApp } from 'vue' createAp ...
- Maven高级——属性
属性 自定义属性 定义属性 <!-- 定义属性--> <properties> <spring.version>5.2.10.RELEASE</spring. ...
- Tauri2.0+Vite5聊天室|vue3+tauri2+element-plus仿微信|tauri聊天应用
原创tauri2.0+vue3+pinai2仿QQ/微信客户端聊天Exe程序TauriWinChat. tauri2-vue3-winchat自研vite5+tauri2.0+vue3 setup+e ...
- Android MTP流程
概要 本文的目的是介绍Android系统中MTP的一些相关知识.主要的内容包括:第1部分 MTP简介 对Mtp协议进行简单的介绍.第2部分 MTP框架 介绍Android系统下MTP的框架.第3部分 ...
- nestjs 和 .net DI 使用并注册的区别
核心:对象之间的关系 各种 引用 --- 方便使用各种服务 1. .net 注册服务 三种注册方式 build.Service.Addsigtel 单例 瞬时 等 .addSingtel<IU ...
- yarn serve 不能开启vue项目 the project seem to require yarn but isnot install
error: answer: 删除 yarn.lock 或者使用 npm run serve 替换 ; ps: yarn.lock 是锁定第三方包版本的文件:
- Vue-Router 是干什么的,原理是什么?
传统的项目中,页面的切换和跳转使用的是超链接实现,但是目前的SPA 是基于组件和路由实现的,页面的切换和跳转是由路由机制完成,区别是更新了视图但不重新请求页面: 原理是把url 和组件之间建立映射关系 ...
- Nuxt.js 应用中的 kit:compatibility 事件钩子详解
title: Nuxt.js 应用中的 kit:compatibility 事件钩子详解 date: 2024/10/11 updated: 2024/10/11 author: cmdragon e ...
- 21 如何写出一篇高质量的sci水文
博客配套视频链接: https://www.bilibili.com/video/BV1fW4y1W7dS/ b 站直接看 模型确定, 结果正在跑(或已结束), 目标期刊已定,一般可以定顶刊 从目标期 ...