目录

一、简单介绍

1.1 常见类型

二、时间轴错乱问题

2.1 示例

2.2 示例完整代码

2.3 问题分析

2.4 修复方法

第一步

第二步

2.5 优化后完整代码


一、简单介绍

ECharts 是一款基于 JavaScript 的数据可视化图表库,动态图表是 ECharts 的一个重要应用场景,它可以让数据展示更加生动、直观,帮助用户更好地理解数据的变化趋势。以下是关于 ECharts 动态图表的详细介绍:

1.1 常见类型

  • 动态折线图:展示数据随时间或其他连续变量的变化趋势,比如股票价格走势、气温变化等。动态折线图可以通过定时更新数据,实时反映最新的变化情况。
  • 动态柱状图:用于对比不同类别数据的数值大小。动态效果可以是柱状图的增长、缩短,或者柱状图的顺序变换等,常用于展示数据的实时排名、销售业绩的动态对比等。
  • 动态饼图:突出显示各部分在总体中所占的比例。动态效果可以是扇区的大小变化、颜色闪烁等,适合用于展示市场份额的动态变化、不同类别数据占比的实时调整等。
  • 动态散点图:可以展示多个变量之间的关系,通过动态效果(如散点的移动、闪烁)来反映数据的实时变动,常用于分析数据的相关性、异常值的动态监测等。

二、时间轴错乱问题

2.1 示例

Examples - Apache ECharts参考:Examples - Apache ECharts

这是一幅多条折线组成的通过率趋势图,用于展示不同类别(1-1、1-2、1-3 )在多个时间节点(横轴日期)的通过率变化情况。

可以发现,页面出现了时间轴顺序错乱的效果,X 轴日期因字符串排序导致逻辑混乱,日期 0516 本应在 0627 之前,但图表中显示在最右侧,导致时间逻辑混乱。

2.2 示例完整代码

以下是一个完整的 HTML 示例,包含原始数据乱序、排序后再渲染图表的过程:

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8" /><title>折线图</title><!-- 引入 ECharts CDN --><script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script><script src="https://cdn.jsdelivr.net/npm/dayjs/dist/dayjs.min.js"></script><style>/* 给两个图表容器设置样式,避免重叠 */.chart-container {width: 800px; height: 500px; margin-bottom: 30px; /* 上下图表间距 */}</style>
</head>
<body><!-- 图表容器 --><div id="chart1" class="chart-container"></div><script>// ===================== 数据及图表配置 =====================const rawData1 = [['日期', '模块', '通过率'],// Phone - -1['0418', '1-1', 98],['0422', '1-1', 97],['0425', '1-1', 96],['0429', '1-1', 96],['0513', '1-1', 99],['0516', '1-1', '-'],['0523', '1-1', 39],['0527', '1-1', 96],['0530', '1-1', 96],['0603', '1-1', 98],['0627', '1-1', ],['0418', '1-2', 98],['0422', '1-2', 98],['0425', '1-2', 96],['0429', '1-2', 98],['0513', '1-2', 100],['0516', '1-2', 97],['0523', '1-2', 89],['0527', '1-2', 98],['0530', '1-2', 98],['0603', '1-2', 100],['0627', '1-2', 95],['0418', '1-3', 89],['0422', '1-3', 93],['0425', '1-3', 89],['0429', '1-3', 93],['0513', '1-3', 97],['0516', '1-3', '-'],['0523', '1-3', 90],['0527', '1-3', 95],['0530', '1-3', 95],['0603', '1-3', 91],['0627', '1-3', 92],['0418', '1-4', 95],['0422', '1-4', 93],['0425', '1-4', 96],['0429', '1-4', 93],['0513', '1-4', 97],['0516', '1-4', '-'],['0523', '1-4', 95],['0527', '1-4', 93],['0530', '1-4', 96],['0603', '1-4', 94],['0627', '1-4', '-'],];// 数据预处理:过滤无效值function filterData(data){return data.filter((row, index) => {if (index === 0) return true;     // 跳过表头 & 通过率为'-'的项return row[2] !== '-'; });}// ===================== 通用图表渲染函数 =====================/*** 渲染 ECharts 折线图* @param {string} domId - 容器 DOM ID* @param {array} data - 原始数据(格式:[['日期','维度','值'], ...])* @param {string} groupKey - 分组维度(如 '模块' 或 '机型_模块')* @param {string} titleText - 图表标题*/function renderEChart(domId, data, groupKey, titleText) {const myChart = echarts.init(document.getElementById(domId));const groups = [...new Set(data.map(item => item[1]))]; // 提取分组(如模块、机型_模块)const datasetWithFilters = [];const seriesList = [];groups.forEach(group => {const datasetId = `dataset_${group}`;datasetWithFilters.push({id: datasetId,fromDatasetId: 'dataset_raw',transform: {type: 'filter',config: { dimension: groupKey, '=': group }}});seriesList.push({type: 'line',datasetId: datasetId,showSymbol: true,name: group,endLabel: {show: true,formatter: (params) => `${params.value[1]}`},emphasis: { focus: 'series' },encode: {x: '日期',y: '通过率',label: [groupKey, '通过率'],itemName: '日期',tooltip: ['通过率'],seriesName: '模块'}});});const option = {animationDuration: 2000,seriesLayoutBy: 'seriesName',dataset: [{ id: 'dataset_raw', source: data },...datasetWithFilters],title: { text: titleText, left: 'center' },tooltip: {trigger: 'axis', order: 'valueDesc',axisPointer: { type: 'shadow' } // 鼠标指向时显示阴影指示器,增强交互},xAxis: { type: 'category',nameLocation: 'middle'},yAxis: {type: 'value',name: '通过率(%)',min: 10, // 过滤过低无效值(如测试阶段的异常值)max: 100, // 固定最大值为 100%,避免刻度溢出interval: 10 // 刻度间隔设为 10%,减少刻度密度},grid: {right: 150, // 从 100 调整为 150,增加右侧空间left: 60, // 左侧预留足够空间显示 Y 轴名称top: 50,bottom: 80 // 底部增加空间,避免 X 轴日期重叠},series: seriesList};myChart.setOption(option);}// ===================== 调用函数渲染图表 =====================renderEChart('chart1', filterData(rawData1),'模块', '通过率趋势');</script>
</body>
</html>

2.3 问题分析

多条折线的data中存在“-”,是因为我想要展示有的折线不存在该日期的数据,使用“-”来表示无数据情况。

从代码中可以看出 X 轴绘制是用的category 类型,是直接赋值渲染。category 类型的 X 轴,会严格按照 xAxis.data 数组的顺序展示类目。

发现直接赋值渲染,则页面会出现时间轴顺序错乱的效果。 

2.4 修复方法

第一步

重新修改折线图数据规则:需展示全量日期序列,无对应值的日期保留空数据占位。

例如,折线中的某一天数据为['0516', '1-3', '-'],时,其完整数据需包含所有日期节点,无值节点以空项填充,最终格式['0516', '1-3', ]。如下图所示,

修改后保存html文件,重新用浏览器打开。

经过第一步修改后的展示效果如下图所示。

当前展示效果中,X 轴的日期能按正常逻辑显示 ,但 1-1、1-3、1-4折线图都因存在无对应值的日期节点(数据中以空项形式呈现 ),在可视化呈现时出现了折线断裂(断层)的情况;而 1-2 折线图由于数据完整度较好,未出现此类问题,展示状态正常 。

第二步

参考:Documentation - Apache ECharts  配置文件

经过第一步修改后的展示效果中出现折线断裂情况。是因为,ECharts中的默认行为是若数据中存在 null(或空值占位 ),折线会在 null 处断裂,不连接两侧的有效点。

我们可以使用connectNulls这个属性来解决。

在 ECharts 中,connectNulls 是系列(series) 的配置属性,用于设置是否连接折线图中 null 数据点两侧的有效数据点。而connectNulls: true 是 ECharts 中折线图(line 系列) 的关键配置,用于控制包含 null 数据点时,折线是否连接两侧的有效数据,解决折线 “断层” 问题。

具体修改方法如下,

修改后保存html文件,重新用浏览器打开。

经过第二步修改后的展示效果如下图所示。

从展示效果来看, X 轴呈现的是从 0418 到 0627 的时间序列,此前因日期以字符串形式按字典序排序出现乱序状况。经修复后,如今日期已能依照正常的时间逻辑有序排列,保障了时间维度展示的准确性,为基于时间序列分析各系列通过率趋势筑牢基础,让数据随时间的变化呈现更贴合实际业务进程。

2.5 优化后完整代码

<!DOCTYPE html>
<html lang="zh-CN">
<head><meta charset="UTF-8" /><title>折线图</title><!-- 引入 ECharts CDN --><script src="https://cdn.jsdelivr.net/npm/echarts/dist/echarts.min.js"></script><script src="https://cdn.jsdelivr.net/npm/dayjs/dist/dayjs.min.js"></script><style>/* 给两个图表容器设置样式,避免重叠 */.chart-container {width: 800px; height: 500px; margin-bottom: 30px; /* 上下图表间距 */}</style>
</head>
<body><!-- 图表容器 --><div id="chart1" class="chart-container"></div><script>// ===================== 数据及图表配置 =====================const rawData1 = [['日期', '模块', '通过率'],// Phone - -1['0418', '1-1', 98],['0422', '1-1', 97],['0425', '1-1', 96],['0429', '1-1', 96],['0513', '1-1', 99],['0516', '1-1', ],['0523', '1-1', 39],['0527', '1-1', 96],['0530', '1-1', 96],['0603', '1-1', 98],['0627', '1-1', ],['0418', '1-2', 98],['0422', '1-2', 98],['0425', '1-2', 96],['0429', '1-2', 98],['0513', '1-2', 100],['0516', '1-2', 97],['0523', '1-2', 89],['0527', '1-2', 98],['0530', '1-2', 98],['0603', '1-2', 100],['0627', '1-2', 95],['0418', '1-3', 89],['0422', '1-3', 93],['0425', '1-3', 89],['0429', '1-3', 93],['0513', '1-3', 97],['0516', '1-3', ],['0523', '1-3', 90],['0527', '1-3', 95],['0530', '1-3', 95],['0603', '1-3', 91],['0627', '1-3', 92],['0418', '1-4', 95],['0422', '1-4', 93],['0425', '1-4', 96],['0429', '1-4', 93],['0513', '1-4', 97],['0516', '1-4', ],['0523', '1-4', 95],['0527', '1-4', 93],['0530', '1-4', 96],['0603', '1-4', 94],['0627', '1-4', ],];// 数据预处理:过滤无效值function filterData(data){return data.filter((row, index) => {if (index === 0) return true;     // 跳过表头 & 通过率为'-'的项return row[2] !== '-'; });}// ===================== 通用图表渲染函数 =====================/*** 渲染 ECharts 折线图* @param {string} domId - 容器 DOM ID* @param {array} data - 原始数据(格式:[['日期','维度','值'], ...])* @param {string} groupKey - 分组维度(如 '模块' 或 '机型_模块')* @param {string} titleText - 图表标题*/function renderEChart(domId, data, groupKey, titleText) {const myChart = echarts.init(document.getElementById(domId));const groups = [...new Set(data.map(item => item[1]))]; // 提取分组(如模块、机型_模块)const datasetWithFilters = [];const seriesList = [];groups.forEach(group => {const datasetId = `dataset_${group}`;datasetWithFilters.push({id: datasetId,fromDatasetId: 'dataset_raw',transform: {type: 'filter',config: { dimension: groupKey, '=': group }}});seriesList.push({type: 'line',connectNulls: true,datasetId: datasetId,showSymbol: true,name: group,endLabel: {show: true,formatter: (params) => `${params.value[1]}`},emphasis: { focus: 'series' },encode: {x: '日期',y: '通过率',label: [groupKey, '通过率'],itemName: '日期',tooltip: ['通过率'],seriesName: '模块'}});});const option = {animationDuration: 2000,seriesLayoutBy: 'seriesName',dataset: [{ id: 'dataset_raw', source: data },...datasetWithFilters],title: { text: titleText, left: 'center' },tooltip: {trigger: 'axis', order: 'valueDesc',axisPointer: { type: 'shadow' } // 鼠标指向时显示阴影指示器,增强交互},xAxis: { type: 'category',nameLocation: 'middle'},yAxis: {type: 'value',name: '通过率(%)',min: 10, // 过滤过低无效值(如测试阶段的异常值)max: 100, // 固定最大值为 100%,避免刻度溢出interval: 10 // 刻度间隔设为 10%,减少刻度密度},grid: {right: 150, // 从 100 调整为 150,增加右侧空间left: 60, // 左侧预留足够空间显示 Y 轴名称top: 50,bottom: 80 // 底部增加空间,避免 X 轴日期重叠},series: seriesList};myChart.setOption(option);}// ===================== 调用函数渲染图表 =====================renderEChart('chart1', filterData(rawData1),'模块', '通过率趋势');</script>
</body>
</html>

通过以上步骤,就能解决 category 类型 X 轴显示乱序的问题,让 X 轴按照你期望的固定顺序展示类目啦。

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

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

相关文章

网络安全之注入攻击:原理、危害与防御之道

网络安全之注入攻击&#xff1a;原理、危害与防御之道 引言 在OWASP Top 10安全风险榜单中&#xff0c;注入攻击常年占据首位。2023年Verizon数据泄露调查报告显示&#xff0c;67%的Web应用漏洞与注入类攻击直接相关。本文从技术视角系统解析注入攻击的核心原理、典型场景及防御…

Python爬虫动态IP代理报错全解析:从问题定位到实战优化

目录 一、代理IP失效&#xff1a;爬虫的"隐形杀手" 1.1 失效场景复现 1.2 解决方案 二、403封禁&#xff1a;反爬机制的"精准打击" 2.1 封禁原理剖析 2.2 破解方案 三、速度瓶颈&#xff1a;代理性能的"致命短板" 3.1 性能对比测试 3.2…

机器学习基础知识【 激活函数、损失函数、优化器、 正则化、调度器、指标函数】

目录标题机器学习基础知识概览激活函数 (Activation Functions)损失函数 (Loss Functions / Cost Functions)优化器 (Optimizers)正则化 (Regularization)调度器 (Schedulers / Learning Rate Schedulers)指标函数 (Metric Functions)其他重要概念训练流程机器学习基础知识概览…

【达梦数据库|JPA】后端数据库国产化迁移记录

项目背景 经典的springbootjpa&#xff0c;java1.8数据库MySQL需要迁移到国产化数据库达梦上 开发环境安装 最简单的方式&#xff1a; 官方网站下载安装时选择“典型安装”即可 Linux安装 国产化一律上docer不要犹豫 下载三方提供的docker镜像按页面文档启动即可同上下载官…

ubuntu22默认安装firefox使用snap安装还老打不开解决办法

终极解决方案&#xff08;100% 避免 Snap 版 Firefox&#xff09; 步骤 1&#xff1a;彻底移除 Snap 版 Firefox bash sudo snap remove --purge firefox 步骤 2&#xff1a;添加 Mozilla 官方 PPA&#xff08;提供 .deb 版 Firefox&#xff09; bash sudo add-apt-repository …

MyBatis02-mybatis-config.xml配置文件讲解

mybatis-config.xml 是 MyBatis 的核心配置文件&#xff0c;用于配置整个 MyBatis 框架的全局行为&#xff0c;比如环境&#xff08;数据源&#xff09;、事务、类型别名、插件、Mapper 映射等。示例&#xff1a;<?xml version"1.0" encoding"UTF-8" ?…

合上电脑不关机

在Debian 系统上&#xff0c;如何实现合上电脑不关机的效果&#xff1f; 可以修改配置文件&#xff1a; sudo vim /etc/systemd/logind.conf1.找到 HandleLidSwitch &#xff0c;将其值改为 ignore &#xff08;处理盖子开关为忽略&#xff09; 2.将 LidSwitchIgnoreInhibited …

服务器深夜告警?可能是攻击前兆!

凌晨三点&#xff0c;刺耳的告警铃声把你从梦中惊醒&#xff1a;服务器CPU 100%&#xff0c;内存耗尽&#xff01;你手忙脚乱地登录服务器&#xff0c;发现某个进程疯狂占用资源。是程序Bug&#xff1f;还是业务突增&#xff1f;排查半天&#xff0c;最后在角落的日志里发现蛛丝…

重学前端003 --- CSS 颜色

文章目录文档声明head颜色模型div根据在这里 Freecodecamp 实践&#xff0c;记录笔记总结。 文档声明 在文档顶部添加 DOCTYPE html 声明 <!DOCTYPE html>head title 元素为搜索引擎提供了有关页面的额外信息。 它还通过以下两种方式显示 title 元素的内容&#xff1a…

学弟让我帮忙写一个学生管理系统的后端,我直接上科技

&#x1f4dd;个人主页&#xff1a;哈__ 期待您的关注 目录 一、飞算AI简介 二、系统开发 2.1 需求提出 2.2 系统模块的设计 2.3 数据库表格设计 2.4 接口规范设计 2.5 源码生成 三、总结 学弟这两天有一个小组合作的任务&#xff0c;应该是培训吧要写一个学生管理…

《P3038 [USACO11DEC] Grass Planting G》

题目描述 给出一棵有 n 个节点的树&#xff0c;有 m 个如下所示的操作&#xff1a; 将两个节点之间的 路径上的边 的权值均加一。 查询两个节点之间的 那一条边 的权值&#xff0c;保证两个节点直接相连。 初始边权均为 0。 输入格式 第一行两个整数 n,m&#xff0c;含义…

NestJS

文章的地址 NestJShttps://equinox-primrose-ceb.notion.site/NestJS-22d4b8031e0f80b39fc7fe1ff111f802 不产生测试的.spec.ts文件的配置 "generateOptions": {"spec": false }创建模型 nest g m xx 创建服务 nest g s xx 创建处理 nest g c xx CRU…

vue入门学习教程

一、介绍 vue是一款用于构建用户界面的 JavaScript 框架。基于标准 HTML、CSS 和 JavaScript 构建&#xff0c;并提供了一套声明式的、组件化的编程模型&#xff0c;帮助你高效地开发用户界面。 二、使用和安装 方法1&#xff1a;在html代码中直接使用<script>导入&…

C++类对象多态基础语法【超详细】

文章目录前言1. 虚函数1.1 现象1.2 多态1.3 析构函数1.4 override和final1.5 重载、隐藏、重写对比2. 抽象类2.1 抽象类特性2.2 抽象类的应用场景3. 多态实现的底层原理4. 静态绑定和动态绑定5. 总结前言 多态是面向对象三大特性之一&#xff0c;也是细节最多的语法之一。学习…

Flask 入门到实战(3):用 SQLAlchemy 优雅操作数据库

深入理解 Flask ORM&#xff1a;用 SQLAlchemy 优雅操作数据库一、前言&#xff1a;什么是 ORM&#xff1f;为什么要用它&#xff1f; 传统数据库操作要写 SQL&#xff0c;比如&#xff1a; SELECT * FROM users WHERE id 1;而使用 ORM 后&#xff0c;你可以这样写&#xff1a…

源表=电源+数字表?一文看懂SMU源表 2025-04-14

源表(Source Meter Unit, SMU)广泛用于半导体器件、材料、医疗、发光器件与光通信等行业,测量器件的伏安(I-V)特性曲线、绝缘材料的电阻值(电阻率)、电容的绝缘电阻(漏电流)、光电器件的暗电流或者L-I-V等。 源表的名称已经清晰的告诉我们,它包含了高精度电源输出和…

单片机STM32F103:DMA的原理以及应用

STM32F103系列微控制器&#xff08;基于ARM Cortex-M3内核&#xff09;集成了**DMA&#xff08;Direct Memory Access&#xff0c;直接内存访问&#xff09;**控制器&#xff0c;用于在存储器与外设、存储器与存储器之间高效传输数据&#xff0c;减少CPU的干预&#xff0c;从而…

Webview 中可用的 VS Code 方法

在 VS Code Webview 的 HTML 中&#xff0c;不能直接调用 VS Code 的 API&#xff08;如 vscode.window.showInformationMessage&#xff09;&#xff0c;但可以通过 acquireVsCodeApi() 获取一个受限的 vscode 对象&#xff0c;用于与插件主程序通信。以下是详细说明和示例&am…

Qt:布局管理器Layout

目录 布局管理器 QVBoxLayout QHBoxLayout QGirdLayout QFormLayout Spacer 布局管理器 在以往的界面操作上&#xff0c;都是程序员手动拖动控件来布局&#xff0c;这种方式有一些不足之处&#xff0c;比如不能很好的把握控件之间的距离&#xff0c;以及控件的大小&…

【Java编程动手学】深入剖析Java网络编程:原理、协议与应用

文章目录一、引言二、计算机网络基础1、计算机网络的概念2、网络地址的重要性三、套接字编程&#xff1a;网络通信的基石1、套接字的概念2、TCP通信编程示例四、TCP通信编程&#xff1a;可靠的数据传输1、TCP协议的特点2、实际应用中的TCP通信五、UDP通信编程&#xff1a;高效的…