Apache ECharts 5.2.0 的新功能
通用轉換
自然且平滑的轉換動畫一直是 Apache ECharts 的重要功能。透過避免資料更新時的突然變化,不僅改善了視覺效果,也提供了表達資料關聯和演變的可能性。因此,在 5.2.0 中,我們進一步增強了此動畫功能。接下來,我們將看看此通用轉換如何為圖表增添表現力和敘事力。
在之前的版本中,轉換動畫有一定的限制:它們只能用於相同形狀的位置、大小,而且只能在相同類型的系列上運作。例如,以下範例透過圓餅圖中扇形形狀的變化來反映資料百分比的變化。
function makeRandomData() { return [ { value: Math.random(), name: 'A' }, { value: Math.random(), name: 'B' }, { value: Math.random(), name: 'C' } ]; } option = { series: [ { type: 'pie', radius: [0, '50%'], data: makeRandomData() } ] }; setInterval(() => { myChart.setOption({ series: { data: makeRandomData() } }); }, 2000);
從 5.2.0 開始,我們引入了通用轉換,這是一個更強大的動畫功能。有了它,轉換不再侷限於相同類型的系列之間。現在,我們可以使用這種跨系列的變形來在任何類型的系列和任何類型的形狀之間進行動畫處理。
這有多酷?讓我們看看!
跨系列的變形轉換
將 universalTransition: true
設定為啟用通用轉換功能,從圓餅圖切換到長條圖,或從長條圖切換到散佈圖,甚至在更複雜的圖表(如旭日圖和樹狀圖)之間切換,都可以自然地變形。
如下所示,在圓餅圖和長條圖之間切換。
const dataset = { dimensions: ['name', 'score'], source: [ ['Hannah Krause', 314], ['Zhao Qian', 351], ['Jasmin Krause ', 287], ['Li Lei', 219], ['Karle Neumann', 253], ['Mia Neumann', 165], ['Böhm Fuchs', 318], ['Han Meimei', 366] ] }; const pieOption = { dataset: [dataset], series: [ { type: 'pie', // associate the series to be animated by id id: 'Score', radius: [0, '50%'], universalTransition: true, animationDurationUpdate: 1000 } ] }; const barOption = { dataset: [dataset], xAxis: { type: 'category' }, yAxis: {}, series: [ { type: 'bar', // associate the series to be animated by id id: 'Score', // Each data will have a different color colorBy: 'data', encode: { x: 'name', y: 'score' }, universalTransition: true, animationDurationUpdate: 1000 } ] }; option = barOption; setInterval(() => { option = option === pieOption ? barOption : pieOption; // Use the notMerge form to remove the axes myChart.setOption(option, true); }, 2000);
常用圖表之間更多的轉換。
這種轉換不再侷限於基本折線圖、長條圖和圓餅圖,也可以在長條圖和地圖之間進行
或在旭日圖和樹狀圖之間,甚至是非常靈活的自訂系列之間也可以進行轉換。
請注意,您需要設定系列 ID,以確保需要動畫轉換的系列之間存在一對一的對應關係。
最小捆綁包需要手動導入此功能。
import { UniversalTransition } from 'echarts/features'; echarts.use([UniversalTransition]);
資料分割和合併動畫
除了資料值的常見更新之外,有時我們還會在互動後遇到資料聚合、向下鑽取和其他更新,此時我們無法直接應用一對一的轉換,而是需要使用更多像分割和合併這樣的動畫效果來表達資料的轉換。
為了能夠表達資料之間可能的多對多連線,在 5.2.0 中,我們引入了一個新概念 groupId
。我們可以透過 series.dataGroupId 將群組設定為整個系列,或透過 series.data.groupId 更精細地設定每個資料所屬的群組。如果您使用 dataset
來管理資料,則更簡單,您可以使用 encode.itemGroupId
來指定編碼為 groupId
的維度。
例如,如果我們想為長條圖實現向下鑽取動畫,我們可以將向下鑽取後的所有資料系列設定為相同的 groupId
,然後對應到向下鑽取前的資料
option = { xAxis: { data: ['Animals', 'Fruits', 'Cars'] }, yAxis: {}, dataGroupId: '', animationDurationUpdate: 500, series: { type: 'bar', id: 'sales', data: [ { value: 5, groupId: 'animals' }, { value: 2, groupId: 'fruits' }, { value: 4, groupId: 'cars' } ], universalTransition: { enabled: true, divideShape: 'clone' } } }; const drilldownData = [ { dataGroupId: 'animals', data: [ ['Cats', 4], ['Dogs', 2], ['Cows', 1], ['Sheep', 2], ['Pigs', 1], ['Cows', 1], ['Sheep', 2], ['Pigs', 1] ] }, { dataGroupId: 'fruits', data: [ ['Apples', 4], ['Oranges', 2], ['Oranges', 2] ] }, { dataGroupId: 'cars', data: [ ['Toyota', 4], ['Opel', 2], ['Volkswagen', 2], ['Volkswagen', 2] ] } ]; myChart.on('click', event => { if (event.data) { const subData = drilldownData.find(data => { return data.dataGroupId === event.data.groupId; }); if (!subData) { return; } myChart.setOption({ xAxis: { data: subData.data.map(item => { return item[0]; }) }, series: { type: 'bar', id: 'sales', dataGroupId: subData.dataGroupId, data: subData.data.map(item => { return item[1]; }), universalTransition: { enabled: true, divideShape: 'clone' } }, graphic: [ { type: 'text', left: 50, top: 20, style: { text: 'Back', fontSize: 18 }, onclick: function() { myChart.setOption(option, true); } } ] }); } });
透過 groupId
,我們還可以實現更豐富的聚合和向下鑽取動畫。
資料聚合。
將單一系列向下鑽取為兩個系列
通用轉換將表達資料關係和演變的能力提升到新的層次,為您的視覺化創作靈感插上翅膀。
此時,我們知道您已經迫不及待地想試試了。但別擔心,5.2.0 中還有更多值得查看的新功能。
調色板選擇策略
在上面的通用轉換範例中,您可能已經注意到我們使用了一個在之前版本中不可用的 colorBy
設定。此設定也是我們在此版本中新增的一項新功能,用於設定系列調色板顏色選擇的不同粒度。此設定目前支援兩種策略。
'series'
按系列分配調色板中的顏色,因此同一系列中的所有資料都使用相同的顏色。'data'
根據資料項目分配調色板中的顏色,每個資料項目使用不同的顏色。
先前,我們為每種類型的系列固定此策略,例如,長條圖固定為 'series'
,圓餅圖固定為 'data'
。
現在有了這項新功能,我們可以為長條圖中的每個資料項目分配不同的顏色。
option = { xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] }, yAxis: { type: 'value' }, series: [ { data: [120, 200, 150, 80, 70, 110, 130], type: 'bar', colorBy: 'data' } ] };
或在圓餅圖中統一使用一種顏色。
option = { series: { type: 'pie', colorBy: 'series', radius: [0, '50%'], itemStyle: { borderColor: '#fff', borderWidth: 1 }, data: [ { value: 335, name: 'Direct Visit' }, { value: 234, name: 'Union Ad' }, { value: 1548, name: 'Search Engine' } ] } };
此設定使我們能夠避免尋找調色板顏色並逐一設定它們的麻煩,並且可以在特定場景中提供便利。我們稍後將進一步增強此設定以提供更多策略。
極座標長條圖的標籤
在此版本中,我們為極座標上的長條圖實作了標籤,並支援豐富的標籤定位設定。以下是一個進度圖,標籤顯示在起始點。
option = { angleAxis: { show: false, max: 10 }, radiusAxis: { show: false, type: 'category', data: ['AAA', 'BBB', 'CCC', 'DDD'] }, polar: {}, series: [ { type: 'bar', data: [3, 4, 5, 6], colorBy: 'data', roundCap: true, label: { show: true, // Try changing it to 'insideStart' position: 'start', formatter: '{b}' }, coordinateSystem: 'polar' } ] };
更多標籤位置的設定。
此彈性的標籤位置設定項目極大地豐富了極座標長條圖的表現力,使文字能夠清楚地與對應的資料匹配。
空資料的圓餅圖樣式
在之前的版本中,如果圓餅圖中沒有資料,螢幕可能會完全空白。由於沒有視覺元素,使用者可能會懷疑是否有錯誤。
為了解決這個問題,在此版本中,當沒有資料時,我們預設會顯示一個灰色佔位符圓圈,以防止螢幕完全空白。我們可以使用 emptyCircleStyle
設定此佔位符圓圈的樣式。
option = { series: [ { type: 'pie', data: [], // showEmptyCircle: false, emptyCircleStyle: { // change the style to empty circle color: 'transparent', borderColor: '#ddd', borderWidth: 1 } } ] };
如果您不想顯示此灰色圓圈,也可以將 showEmptyCircle: false
設定為關閉它。
高維度資料的效能增強
自 4.0 以來,我們引入了 dataset 來管理圖表資料。但是,在某些具有特別高維度 ( >100) 資料的極端情況下,我們可能會遇到一些顯著的效能下降,例如以下透過一千個系列視覺化一千維度資料的情況 (#11907),甚至可能導致卡頓。
const indices = Array.from(Array(1000), (_, i) => {
return `index${i}`;
});
const option = {
xAxis: { type: 'category' },
yAxis: {},
dataset: {
// dimension: ['date', . . indices],
source: Array.from(Array(10), (_, i) => {
return {
date: i,
... .indices.reduce((item, next) => {
item[next] = Math.random() * 100;
return item;
}, {})
};
})
},
series: indices.map(index => {
return { type: 'line', name: index };
})
};
此效能問題的原因是我們根據需要在每個系列的底部處理高維度資料集,並儲存一份處理過的資料副本和有關資料維度的元資訊。這意味著在範例中必須處理和儲存 1000 x 1000
個維度,這對記憶體和垃圾回收造成了巨大的壓力,導致高維度的效能顯著下降。
在新版本中,我們已最佳化此問題,以便所有系列盡可能共用資料集儲存 (是否共用取決於系列如何使用資料)。此最佳化確保記憶體不會隨著資料集維度和系列的增加而爆炸,從而顯著提高了這種極端情況下的初始化效能。剛才描述的範例的渲染時間也已縮短到可接受的 300 毫秒或更短。
從這種最佳化中獲益的不僅僅是這種高維度情況。當使用大量資料的資料集時,由於資料共用,多個系列只會處理一次資料,因此也可以帶來顯著的效能提升。
自訂系列的類型最佳化
自訂序列提供了非常彈性的方式來建立序列圖表。相較於其他序列,自訂序列的學習曲線可能稍微陡峭。因此,在這個版本中,我們進一步優化了自訂序列中核心方法 renderItem
的類型,使其能夠更精確地推斷 renderItem
的參數和回傳值的類型,以便根據回傳的類型推斷可以設定元素的哪些屬性。
series = {
type: 'custom',
renderItem(params) {
return {
type: 'group',
// The group type uses children to store children of other types
children: [
{
type: 'circle',
// circle has the following configurable shape attributes
shape: { r: 10, cx: 0, cy: 0 },
// Configurable styles
style: { fill: 'red' }
},
{
type: 'rect',
// rect has the following configurable shape properties
shape: { x: 0, y: 0, width: 100, height: 100 }
},
{
type: 'path',
// Custom path shapes
shape: { d: '...' }
}
]
};
}
};
總結
如果您對 5.2.0 版本中的某些功能和優化感興趣,您可能想更新到最新版本的 Apache ECharts 並親自試用。
如果您對 Apache ECharts 的未來發展感興趣,您也可以追蹤我們在 GitHub Milestone 上的開發計畫。歡迎加入我們成為貢獻者(在 Wiki 瞭解更多資訊)。
完整變更日誌
查看變更日誌