需求

  • 展示未来未来36个月(等分为3个时间范围)的经济效益趋势,3个等分时间区域在趋势图上方常显,不同时间区域之间通过灰色虚线间隔开;
  • 鼠标hover趋势图每个1/3区域,对应区域会有以下3个效果:
    1. 时间范围卡片高亮;
    2. 趋势图上方展示对应指标;
    3. 趋势图展示阴影效果;
  • 鼠标hover or 点击趋势图无tooltips

实现方案

将整个需求拆分为三部分:

常态数据展示

数据来源中包含两组数据:baseDatadata,分别为图中底部的蓝线与顶部的灰线;阴影区域展示的为两部分的差值diffData

常态显示可通过baseDatadiffData设置相同值的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再执行相应的计算:

  1. 定义echarts实例的hover事件,获取对应的hoverIndex
  2. 根据hoverIndexdiffData截断为hoverDataunHoverData,并更新optionsseries
  3. 根据hoverIndex选取对应时间区的数据计算calculatedData
  4. 根据hoverIndex渲染时间区高亮和calculatedData展示

实现中遇到的问题

  1. 图像在hover时出现闪烁
  2. hover时机只在hover到数据点上才触发,需求需要在对应时间区
  3. 区域采用图片填充

本文采用的是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对应区域而不是数据点,采用tooltipformatter替代开始的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的更多相关文章

  1. SQLSERVER 使用 ROLLUP 汇总数据,实现分组统计,合计,小计

    表结构: CREATE TABLE [dbo].[Students]( ,) NOT NULL, ) NULL, [Sex] [int] NOT NULL, ) NULL, ) NULL, , ) N ...

  2. PB gird类型数据窗口 设置分组、分组小计、合计

    今天遇到一个需求,gird表格数据如下:  部门  类型 数据   A  类型1  1  A  类型2  2  B  类型1  3  B  类型2  4   合计 10 实际需要显示的结果为:  部门 ...

  3. 简单的angular购物车商品小计

    <!DOCTYPE html> <html lang="en" ng-app="shopApp"> <head> <m ...

  4. C#给DataTable添加序号、C#给DataTable添加合计、小计

    /// <summary>        /// 给DataTable添加序号        /// </summary>        /// <param name= ...

  5. SAP ALV中同一列的不同行显示不同的小数位,并能够总计,小计

    物料数量字段,根据物料类型的不同,来显示不同的小数位:要求有点苛刻: 首先,要能够总计和小计的话,这一列的字段类型必须是数值类型. 这样的话,就不能通过截取的方式改变不同行的小数位. 以下是两种思路: ...

  6. 每日学习心得:SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析)

    2013-8-20 1.    SQL查询表的行列转换/小计/统计(with  rollup,with cube,pivot解析) 在实际的项目开发中有很多项目都会有报表模块,今天就通过一个小的SQL ...

  7. VMProtect使用小计【一】

    文章列表 VMProtect使用小计[一] – 初次使用VMProtect使用小计[二] – 加壳查看VMProtect使用小计[三] – 权限管理 说明 VMProtect的功能我就不说了,详情大家 ...

  8. 用SQL实现统计报表中的"小计"与"合计"的方法详解

    本篇文章是对使用SQL实现统计报表中的"小计"与"合计"的方法进行了详细的分析介绍,需要的朋友参考下   客户提出需求,针对某一列分组加上小计,合计汇总.网上找 ...

  9. 【IOS实例小计】今日开贴,记录我的ios学习生涯,留下点滴,留下快乐,成荫后人。

    今天开贴来记录自己的ios学习过程,本人目前小白一个,由于对ios感兴趣,所以开始学习,原职java程序,呵呵,勿喷. 本次的[ios实例小计]主要参考一文http://blog.sina.com.c ...

  10. SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析)

    SQL查询表的行列转换/小计/统计(with rollup,with cube,pivot解析) 2013-8-20 1.    SQL查询表的行列转换/小计/统计(with  rollup,with ...

随机推荐

  1. TS-TCC: 通过时序和上下文对比学习时间序列表征《Time-Series Representation Learning via Temporal and Contextual Contrasting》(时间序列、时序表征、时间和上下文对比、对比学习、自监督学习、半监督学习)

    现在是2023年11月14日的22:15,肝不动了,要不先回寝室吧,明天把这篇看了,然后把文档写了.OK,明天的To Do List. 现在是2023年11月15日的10:35,继续. 论文:Time ...

  2. [TK] 一心净士 hzoj-tg-937-2

    万元申万的(不是) 嗯... 另外,这道题其实叫一心净士(shi) 而不是一心净土. 剖析 我们注意到题目要让我们使最小的自然数最大,那么我们的每一个区间都要从零开始放. 显然,假如我们所有区间里最小 ...

  3. 一次基于AST的大规模代码迁移实践

    作者:来自 vivo 互联网大前端团队- Wei Xing 在研发项目过程中,我们经常会遇到技术架构迭代更新的需求,通过技术的迭代更新,让项目从新的技术特性中受益,但由于很多新的技术迭代版本并不能完全 ...

  4. Shell分析服务器日志命令

    1.查看有多少个IP访问: awk '{print $1}' log_file|sort|uniq|wc -l 2.查看某一个页面被访问的次数: grep "/index.php" ...

  5. .NET 8.0 酒店管理系统设计与实现

    前言 给大家推荐一个基于.NET 8.0 的中小型酒店设计的管理系统. 随着酒店的日常工作增加,很难用人工去进行处理一些繁琐的数据,也可能会因为人工的失误而造成酒店的损失,因此需要一款可以协助酒店进行 ...

  6. Oracle ADG 自动切换脚本分享

    为大家分享一个[Oracle ADG自动切换]的脚本,由云和恩墨工程师HongyeDBA编写,支持Switchover.Failover. 下载链接:https://www.modb.pro/down ...

  7. .Net 中带有 ? 的运算符

    // 带 ? 的表达式 // 1. 三元表达式 // 2. ?? 双问号 // obj1 ?? obj2 如果 obj1 为 空(null) 返回 obj2 // Configure the HTTP ...

  8. 开启 Calico eBPF 数据平面实践

    简介 Calico 从 v3.13 开始,集成了 eBPF 数据平面. 关于什么是 eBPF, 以及 Calico 为什么引入了 eBPF , 并不是本篇文章的重点,感兴趣的朋友可以自行阅读相关文档. ...

  9. 云原生爱好者周刊:Grafana Loki 免费电子书

    云原生一周动态要闻: Apache Log4j 2.17.1 修复远程代码执行漏洞 CNCF 发布 2021 年度报告 极狐(GitLab)发布业内首款"GitNative" De ...

  10. 来看看一台Linux可支持多少个链接 | 漫画

    困惑很多人的并发问题 在网络开发中,我发现有很多同学对一个基础问题始终是没有彻底搞明白.那就是一台服务器最大究竟能支持多少个网络连接?我想我有必要单独发一篇文章来好好说一下这个问题. 很多同学看到这个 ...