Echarts柱狀圖實(shí)現(xiàn)同時(shí)顯示百分比+原始值+匯總值效果實(shí)例
原始效果:
柱狀圖:https://echarts.apache.org/examples/zh/editor.html?c=bar-stack-normalization
二開(kāi)效果1:
核心邏輯
同時(shí)顯示百分比和原始值
label: { show: true, position: 'inside', formatter: (params) => { const rawValue = rawData[params.seriesIndex][params.dataIndex]; const percentage = Math.round(params.value * 1000) / 10; return `${rawValue} \n(${percentage}%)`; } },
顯示匯總值
// Add a new series for displaying total values series.push({ name: 'Total', type: 'bar', stack: 'total', itemStyle: { color: 'rgba(0,0,0,0)' // 透明顏色 }, label: { show: true, position: 'top', formatter: params => `Total: ${totalData[params.dataIndex]}` }, data: totalData.map(value => 0.01) // 微小的值以便能顯示標(biāo)簽但不影響圖形 });
代碼解釋
新增顯示總值的系列:
- 您添加了一個(gè)名為
'Total'
的新系列到series
數(shù)組中。- 這個(gè)系列使用
type: 'bar'
,并且堆疊在名為'total'
的堆棧中,這與其他系列使用的堆棧名稱一致。這確保了柱狀圖的對(duì)齊,即使該系列是不可見(jiàn)的。透明的柱狀圖:
itemStyle
被設(shè)置為color: 'rgba(0,0,0,0)'
,使得該系列的柱狀圖完全透明。這是一個(gè)巧妙的方法,可以確保這些柱狀圖不增加任何可見(jiàn)的元素到圖表中,但仍然可以在它們上面放置標(biāo)簽。標(biāo)簽配置:
label
對(duì)象中的show: true
確保顯示標(biāo)簽。position
設(shè)置為'top'
,因此標(biāo)簽顯示在每個(gè)柱狀圖堆棧的頂部。formatter
函數(shù)自定義了標(biāo)簽的文本。它使用params.dataIndex
獲取totalData
中對(duì)應(yīng)的值,并顯示為Total: {value}
。這提供了關(guān)于每個(gè)類別(星期幾)中所有堆疊元素的總值的清晰信息。帶有微小值的數(shù)據(jù):
- 該系列的
data
數(shù)組被設(shè)置為totalData.map(value => 0.01)
。這將每個(gè)數(shù)據(jù)點(diǎn)設(shè)置為一個(gè)非常小的值(0.01)。這些微小的值的目的是為標(biāo)簽創(chuàng)建一個(gè)占位符,而不影響圖表的實(shí)際可視化。由于柱狀圖本身是透明的,這個(gè)值確保了標(biāo)簽可以正確地定位和顯示,而不會(huì)為柱狀圖增加任何視覺(jué)重量。
分析:
- 使用透明的柱狀圖來(lái)顯示標(biāo)簽:通過(guò)使用透明的柱狀圖,您可以在柱狀圖堆棧的頂部放置標(biāo)簽,而不會(huì)改變圖表的視覺(jué)外觀。這是一種常見(jiàn)的技術(shù),當(dāng)您希望添加額外的信息而不影響數(shù)據(jù)的可視化時(shí)。
- 數(shù)據(jù)中的微小值:使用微小值(0.01)確保標(biāo)簽與柱狀圖相關(guān)聯(lián),但不會(huì)顯著地影響堆疊柱狀圖的高度。這在ECharts中尤其有用,因?yàn)闃?biāo)簽是與特定的數(shù)據(jù)點(diǎn)相關(guān)聯(lián)的。
- 堆疊配置:使用相同的堆疊標(biāo)識(shí)符('total')使透明柱狀圖與其余堆疊柱狀圖完美對(duì)齊,確保標(biāo)簽位置的一致性。
這種方法對(duì)于突出顯示總值,同時(shí)保持?jǐn)?shù)據(jù)可視化的完整性非常有效。這是一個(gè)為圖表提供額外信息而不使其變得混亂或扭曲的巧妙解決方案。
完整版代碼
// There should not be negative values in rawData const rawData = [ [100, 302, 301, 334, 390, 330, 320], [320, 132, 101, 134, 90, 230, 210], [220, 182, 191, 234, 290, 330, 310], [150, 212, 201, 154, 190, 330, 410], [820, 832, 901, 934, 1290, 1330, 1320] ]; const totalData = []; for (let i = 0; i < rawData[0].length; ++i) { let sum = 0; for (let j = 0; j < rawData.length; ++j) { sum += rawData[j][i]; } totalData.push(sum); } const grid = { left: 100, right: 100, top: 50, bottom: 50 }; const series = [ 'Direct', 'Mail Ad', 'Affiliate Ad', 'Video Ad', 'Search Engine' ].map((name, sid) => { return { name, type: 'bar', stack: 'total', barWidth: '60%', label: { show: true, position: 'inside', formatter: (params) => { const rawValue = rawData[params.seriesIndex][params.dataIndex]; const percentage = Math.round(params.value * 1000) / 10; return `${rawValue} \n(${percentage}%)`; } }, data: rawData[sid].map((d, did) => totalData[did] <= 0 ? 0 : d / totalData[did] ) }; }); // Add a new series for displaying total values series.push({ name: 'Total', type: 'bar', stack: 'total', itemStyle: { color: 'rgba(0,0,0,0)' // 透明顏色 }, label: { show: true, position: 'top', formatter: params => `Total: ${totalData[params.dataIndex]}` }, data: totalData.map(value => 0.01) // 微小的值以便能顯示標(biāo)簽但不影響圖形 }); option = { legend: { selectedMode: false }, grid, yAxis: { type: 'value' }, xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, series };
二開(kāi)效果2:
完整版代碼
// There should not be negative values in rawData const rawData = [ [100, 302, 301, 334, 390, 330, 320], [320, 132, 101, 134, 90, 230, 210], [220, 182, 191, 234, 290, 330, 310], [150, 212, 201, 154, 190, 330, 410], [820, 832, 901, 934, 1290, 1330, 1320] ]; const totalData = []; for (let i = 0; i < rawData[0].length; ++i) { let sum = 0; for (let j = 0; j < rawData.length; ++j) { sum += rawData[j][i]; } totalData.push(sum); } const grid = { left: 100, right: 100, top: 50, bottom: 50 }; const series = [ 'Direct', 'Mail Ad', 'Affiliate Ad', 'Video Ad', 'Search Engine' ].map((name, sid) => { return { name, type: 'bar', stack: 'total', barWidth: '60%', label: { show: true, position: 'inside', // Position the labels on top of the bars formatter: (params) => { const originalValue = rawData[sid][params.dataIndex]; const percentage = (originalValue / totalData[params.dataIndex] * 100).toFixed(2); return `${originalValue} \n(${percentage}%)`; }, }, data: rawData[sid].map((d, did) => totalData[did] <= 0 ? 0 : d / totalData[did] ) }; }); option = { tooltip: { trigger: 'axis', axisPointer: { type: 'shadow' }, formatter: (params) => { const total = totalData[params[0].dataIndex]; const header = `<div style="font-weight:bold">${params[0].axisValue}</div> <div>Total: ${total}</div>`; const body = params.map(param => { const originalValue = rawData[param.seriesIndex][param.dataIndex]; const percentage = (originalValue / total * 100).toFixed(2); return `<div>${param.seriesName}: ${originalValue} (${percentage}%)</div>`; }).join(''); return header + body; } }, legend: { selectedMode: false }, grid, yAxis: { type: 'value' }, xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, series };
實(shí)現(xiàn)思路與修改:
計(jì)算每天的總訪問(wèn)數(shù):首先遍歷
rawData
并計(jì)算每一天所有來(lái)源的總訪問(wèn)數(shù)。這些總數(shù)被存儲(chǔ)在totalData
數(shù)組中。配置每個(gè)數(shù)據(jù)源系列:為每一個(gè)數(shù)據(jù)源創(chuàng)建一個(gè)
series
對(duì)象。每個(gè)系列代表一種訪問(wèn)來(lái)源,并包含一些配置選項(xiàng),如類型、堆疊設(shè)置、標(biāo)簽顯示方式等。配置標(biāo)簽顯示:為了讓用戶在圖表上直觀地看到原始值和占比,我們需要在每個(gè)柱形上添加標(biāo)簽。標(biāo)簽的內(nèi)容包括原始值和百分比。
配置提示框(Tooltip):為了提供更豐富的信息,我們配置了一個(gè)提示框,當(dāng)用戶懸停在柱形上時(shí)會(huì)顯示當(dāng)天的總訪問(wèn)數(shù)和各個(gè)來(lái)源的具體數(shù)值及占比。
二開(kāi)效果3:
完整版代碼
// There should not be negative values in rawData const rawData = [ [100, 302, 301, 334, 390, 330, 320], [320, 132, 101, 134, 90, 230, 210], [220, 182, 191, 234, 290, 330, 310], [150, 212, 201, 154, 190, 330, 410], [820, 832, 901, 934, 1290, 1330, 1320] ]; const totalData = []; for (let i = 0; i < rawData[0].length; ++i) { let sum = 0; for (let j = 0; j < rawData.length; ++j) { sum += rawData[j][i]; } totalData.push(sum); } const grid = { left: 100, right: 100, top: 50, bottom: 50 }; const series = [ 'Direct', 'Mail Ad', 'Affiliate Ad', 'Video Ad', 'Search Engine' ].map((name, sid) => { return { name, type: 'bar', stack: 'total', barWidth: '60%', label: { show: true, position: 'inside', // Position the labels on top of the bars formatter: (params) => { const originalValue = rawData[sid][params.dataIndex]; const percentage = (originalValue / totalData[params.dataIndex] * 100).toFixed(2); return `${originalValue} (${percentage}%)`; }, }, itemStyle: { emphasis: { // focus : 'series', label: { show: true, position: 'top', fontSize: 12, color: 'red', formatter: (params) => totalData[params.dataIndex] } } }, data: rawData[sid].map((d, did) => totalData[did] <= 0 ? 0 : d / totalData[did] ) }; }); option = { legend: { selectedMode: false }, grid, yAxis: { type: 'value' }, xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, series };
解釋:
- 添加了
itemStyle
選項(xiàng),其中包含了emphasis
子項(xiàng)。- 在
emphasis
中設(shè)置了label
,用于在鼠標(biāo)懸停時(shí)顯示總值。emphasis.label.show
設(shè)為true
,表示在鼠標(biāo)懸停時(shí)顯示標(biāo)簽。emphasis.label.position
設(shè)為'bottom'
,使標(biāo)簽顯示在柱子底部。emphasis.label.fontSize
設(shè)為12
,調(diào)整字體大小。emphasis.label.formatter
使用totalData[params.dataIndex]
顯示當(dāng)前柱子對(duì)應(yīng)的總值
柱狀圖轉(zhuǎn)換為條形圖
核心代碼修改,變更xAxis,yAxis 中的 x y 即可
條形圖同時(shí)展示百分比、原始值、匯總值功能
// There should not be negative values in rawData const rawData = [ [100, 302, 301, 334, 390, 330, 320], [320, 132, 101, 134, 90, 230, 210], [220, 182, 191, 234, 290, 330, 310], [150, 212, 201, 154, 190, 330, 410], [820, 832, 901, 934, 1290, 1330, 1320] ]; const totalData = []; for (let i = 0; i < rawData[0].length; ++i) { let sum = 0; for (let j = 0; j < rawData.length; ++j) { sum += rawData[j][i]; } totalData.push(sum); } const grid = { left: 100, right: 100, top: 50, bottom: 50 }; const series = [ 'Direct', 'Mail Ad', 'Affiliate Ad', 'Video Ad', 'Search Engine' ].map((name, sid) => { return { name, type: 'bar', stack: 'total', barWidth: '60%', label: { show: true, position: 'inside', formatter: (params) => { const rawValue = rawData[params.seriesIndex][params.dataIndex]; const percentage = Math.round(params.value * 1000) / 10; return `${rawValue} \n(${percentage}%)`; } }, data: rawData[sid].map((d, did) => totalData[did] <= 0 ? 0 : d / totalData[did] ) }; }); series.push({ name: 'Total', type: 'bar', stack: 'total', itemStyle: { color: 'red' // 透明顏色 }, label: { show: true, // position: 'middle', formatter: params => `Total: ${totalData[params.dataIndex]}` }, data: totalData.map(value => 0.0) // 微小的值以便能顯示標(biāo)簽但不影響圖形 }); option = { legend: { selectedMode: false }, grid, xAxis: { type: 'value' }, yAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, series };
效果展示
總結(jié)
到此這篇關(guān)于Echarts柱狀圖實(shí)現(xiàn)同時(shí)顯示百分比+原始值+匯總值效果的文章就介紹到這了,更多相關(guān)Echarts柱狀圖同時(shí)顯示百分比原始值內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Ajax與Axios的基礎(chǔ)知識(shí)以及詳細(xì)對(duì)比總結(jié)
在Web開(kāi)發(fā)中Ajax和Axios是兩種實(shí)現(xiàn)異步數(shù)據(jù)請(qǐng)求的技術(shù),Ajax可以在不刷新頁(yè)面的情況下與服務(wù)器通信,Axios是一個(gè)基于Promise的HTTP客戶端,簡(jiǎn)化了HTTP請(qǐng)求的過(guò)程,兩者都能處理多種數(shù)據(jù)格式,這篇文章主要介紹了Ajax與Axios的基礎(chǔ)知識(shí)以及詳細(xì)對(duì)比總結(jié),需要的朋友可以參考下2024-09-09- 這篇文章主要介紹了JS實(shí)現(xiàn)左邊列表移到到右邊列表功能,實(shí)現(xiàn)功能主要是左邊的下拉框內(nèi)容添加到右邊的下拉框,支持多選移動(dòng),且同時(shí)將右邊的下拉框?qū)ο笠瞥?,需要的朋友可以參考?/div> 2018-03-03
JavaScript上傳文件時(shí)不用刷新頁(yè)面方法總結(jié)(推薦)
這篇文章主要介紹了JavaScript上傳文件時(shí)不用刷新頁(yè)面方法,用js+css代碼詳細(xì)介紹了操作過(guò)程,需要的朋友可以參考下2017-08-08基于javascript實(shí)現(xiàn)按圓形排列DIV元素(二)
本篇文章主要介紹基于javascript實(shí)現(xiàn)按圓形排列DIV元素的方法,此文著重于介紹怎樣實(shí)現(xiàn)的按圓形排列DIV元素的運(yùn)動(dòng)原理和實(shí)現(xiàn)效果代碼,需要的朋友來(lái)看下吧2016-12-12微信小程序?qū)崿F(xiàn)手勢(shì)解鎖的示例詳解
手勢(shì)解鎖是生活中常用的解鎖方式,本文將通過(guò)微信小程序?qū)崿F(xiàn)手勢(shì)解鎖這一功能,本實(shí)例以工具的形式可以嵌入到不同的項(xiàng)目之中,感興趣的可以了解一下2022-04-04最新評(píng)論