優化 ECharts 多條折線:折線數據不完整導致的X軸日期錯亂問題

目錄

一、簡單介紹

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;高效的…