Apache ECharts 5.3.0 在動畫表達力、渲染效能、伺服器端渲染上做了大幅度的增強,同時也新增了多座標軸刻度自動對齊、tooltip 數值格式化、地圖投影等社群中期盼已久的特性。
接下來就讓我們一起來看一下這些酷炫又實用的功能吧!
關鍵幀動畫
在之前 ECharts 的動畫集中在圖形新增、更新以及移除的過渡動畫上,過渡動畫往往只有開始狀態和結束狀態。為了表達更復雜的動畫效果,我們 5.3.0 中為自定義系列和圖形元件引入了全新的關鍵幀動畫。
下面是一個簡單的通過關鍵幀動畫實現的呼吸動畫的效果。
keyframeAnimation: [
{
duration: 3000,
loop: true,
keyframes: [
{
percent: 0.5,
easing: 'sinusoidalInOut',
scaleX: 0.1,
scaleY: 0.1
},
{
percent: 1,
easing: 'sinusoidalInOut',
scaleX: 1,
scaleY: 1
}
]
}
]
在關鍵幀動畫中,你可以設定動畫時長、緩動、是否迴圈、每個關鍵幀的位置、緩動以及圖形屬性等。而且每個圖形可以同時設定多個不同設定的關鍵幀動畫。靈活的設定讓我們可以實現非常複雜的動畫效果,下面列舉幾個可以應用關鍵幀動畫的場景。
自定義載入動畫
ECharts 預設內建了一個載入動畫,可以呼叫showLoading
顯示。開發者經常會提需求需要更多的載入動畫效果。現在有了關鍵幀動畫後,我們可以通過圖形(graphic)元件配合關鍵幀動畫實現任何想要的載入動畫效果,比如文字描邊動畫或者柱狀圖形狀的載入動畫。
擴充套件更豐富的散點圖動畫特效
帶有特效動畫的散點圖一直以來是 ECharts 的特色功能。開發者可以使用 effectScatter 系列來實現帶有漣漪特效的動態散點圖,這種特效動畫除了讓作品更有趣,也起到了高亮提示使用者的效果。跟載入動畫一樣,開發者也常常提出需要更多動畫效果的需求。現在我們可以在自定義系列中通過使用關鍵幀動畫來實現更復雜的特效。
比如下面例子在 SVG 地圖上給自定義系列繪製的圖釘加上了跳動的動畫效果,同時配上了漣漪動畫。
載入 Lottie 動畫
為了充分發掘出新的關鍵幀動畫的能力,ECharts 團隊的沈毅寫了一個 ,可以將 Lottie 動畫檔案解析成 ECharts 的圖形格式進行渲染。結合 Lottie 的表達力我們可以進一步的在我們的專案中繪製出細膩的動畫:
圖形元件過渡動畫
我們在 5.0 裡為自定義系列中返回的圖形提供了更靈活的過渡動畫設定。可以通過transition
, enterFrom
, leaveTo
三個設定項來設定每個圖形哪些屬性會擁有過渡動畫,當圖形建立和被移除的時候該執行怎麼樣的動畫。例如:
function renderItem() {
//...
return {
//...
x: 100,
// 'style', 'x', 'y' 會被動畫
transition: ['style', 'x', 'y'],
enterFrom: {
style: {
// 淡入
opacity: 0
},
//從左側飛入
x: 0
},
leaveTo: {
// 淡出
opacity: 0
},
// 向右側飛出
x: 200
};
}
在 5.3.0 中我們把這些過渡動畫的設定擴充套件到了圖形(graphic)元件中,並且做了更多的增強:
如果你不想一一寫出每個要動畫的屬性,現在你可以直接設定transition: 'all'
為所有屬性都加上動畫過渡。
與此同時我們還新增了enterAnimation
、updateAnimation
、leaveAnimation
分別設定每個圖形入場、更新、出場動畫的時長(duration)、延遲(delay)和緩動(easing)。除此之外,漸變色現在也支援動畫了。
全新的 SVG 渲染器
在 5.3.0 中我們重構了我們的 SVG 渲染器,新的 SVG 渲染器能夠帶來 2x ~ 10x 的效能提升,在某些特殊場景中甚至能有數十倍的提升。
之前的 SVG 渲染器我們直接從渲染佇列更新到 DOM。但是因為 zrender 的圖形屬性跟 DOM 並不是一一對應的,因此中間需要實現非常複雜的 Diff 邏輯,容易出錯而且在某些場景下效能並不能做到最好。在這個版本我們重構成先全量渲染到 VDOM,然後再將 VDOM patch 到 DOM 完成渲染。全量渲染可以避免複雜的 Diff 邏輯帶來的潛在 Bug。而 VDOM 和 DOM 的一一對應可以保證在 patch 的時候保證更新是最少的,從而帶來巨大的效能提升。
可以給大家帶來比較直觀的效能提升的感受。新的版本在 SVG 模式下拖動的互動上比之前版本流暢非常多。
除了效能的提升,我們還可以使用中間全量渲染得到的 VDom 做更多的事情,比如下面會介紹的伺服器端渲染。
零依賴的伺服器端渲染
在之前的版本 ECharts 也可以實現伺服器端的渲染,但是必須得依賴 ,如果是使用 SVG 模式則需要依賴 來模擬 DOM 環境。這些依賴一是帶來了額外的體積和使用要求,二是也會有更多的效能損耗。
這次新的 SVG 渲染器可以讓我們從中間的 VDOM 渲染得到字串,帶來了完全零依賴的伺服器端渲染,輸出更精簡併且帶有 CSS 動畫的 SVG 字串。
// 在 SSR 模式下第一個引數不需要再傳入 DOM 物件
const chart = echarts.init(null, null, {
renderer: 'svg', // 必須使用 SVG 模式
ssr: true, // 開啟 SSR
width: 400, // 需要指明高和寬
height: 300
});
// 像正常使用一樣 setOption
chart.setOption(...);
// 輸出字串
const svgStr = chart.renderToSVGString();
我們在 CodeSandbox 中搭建一個最簡單的 NodeJS 伺服器然後使用 ECharts 伺服器端渲染的效果:
在此基礎上,我們優化了輸出的 SVG 字串,使其在諸如 PowerPoint 等更多的平臺上有更好的顯示效果。
自定義地圖投影
地圖一直是 ECharts 中使用非常廣泛的元件。一般地圖元件會使用儲存了經緯度的 GeoJSON 格式的資料。而 ECharts 則計算出合適的顯示區域然後把經緯度線性對映到這個區域。這是一種最簡單的地圖投影方式。但是簡單的線性投影並無法滿足某些複雜的地圖場景,例如使用 投影解決線性投影中面積失真的問題,或者在世界地圖中讓太平洋顯示在中間等等。
因此在 5.3.0 裡中我們引入了自定義的地圖投影,可以通過project
和unproject
兩個方法告訴 ECharts 如何投影座標,以及如何根據投影后座標計算經緯度。下面是簡單的使用墨卡託投影的例子:
series = {
type: 'map',
projection: {
project: point => [
(point[0] / 180) * Math.PI,
-Math.log(Math.tan((Math.PI / 2 + (point[1] / 180) * Math.PI) / 2))
],
unproject: point => [
(point[0] * 180) / Math.PI,
((2 * 180) / Math.PI) * Math.atan(Math.exp(point[1])) - 90
]
}
};
除了我們自己實現投影公式,我們也可以使用 等第三方庫提供的現成的投影實現:
const projection = d3.geoConicEqualArea();
// ...
series = {
type: 'map',
projection: {
project: point => projection(point),
unproject: point => projection.invert(point)
}
};
配合在 5.2 裡新增的全域性過渡動畫特性,我們可以實現不同投影效果之間的動畫過渡:
除了地圖的投影之外,我們在這個版本對於地圖還做了下面兩個增強:
-
對 GeoJSON 資料提供了
'LineString'
和'MultiLineString'
的支援。 -
將預設標籤位置的計算從包圍盒中心改為最大區域的重心座標,計算結果更加準確。
多座標軸的刻度對齊
多座標軸的刻度對齊是社群中提了很久的一個需求,我們在網上也可以看到很多開發者寫的如何在 ECharts 中實現座標軸對齊的文章,通常都會比較麻煩而且會有比較多的侷限性。
在 5.3.0 中我們終於引入了數值軸座標軸刻度對齊的功能。可以在需要對齊刻度的座標軸中設定alignTicks: true
。該座標軸就會根據第一個座標軸的刻度劃分去調整自己的刻度,實現自動對齊。
支援高亮和選中狀態的關閉
ECharts 中高亮狀態可以在滑鼠移到圖形上的時候給使用者提供反饋,但是在圖表中有海量圖形的時候,高亮的動畫也可能帶來互動上的效能問題。特別在 tooltip 或者圖例元件聯動觸發的高亮會同時高亮多個圖形。
因此在這個版本中我們新增了emphasis.disabled
設定項。如果不需要高亮的反饋,又對互動效能非常在意的話,可以通過這個設定項來關閉高亮狀態。
與此同時,對於選中狀態,我們也新增了select.disabled
。該設定項可以用於細粒度設定部分資料不可選。
支援整個系列的選中
在 5.3.0 中我們支援將selectedMode
設定為'series'
以實現系列所有資料的選中。
tooltip 中的數值格式化
tooltip 可以在使用者移到圖形上的時候通過提示框顯示更詳細的相關資訊,ECharts 也提供了formatter
回撥函數可以讓開發者更靈活的自定義提示框的內容。
但是我們發現大部分時候開發者只是需要格式化提示框中的數位部分,例如固定精度,加上$
字首等等,而之前為了格式化數位開發者只能通過formatter
重寫整個提示框的內容。特別是在 5.0 後 ECharts 的提示框結構更復雜,樣式更美觀了,重寫變得成本很大而且很難達到預設的效果。
因此在這個版本我們為 tooltip 新增了valueFormatter
設定項用於數值部分的格式化。
還是剛才那個座標軸對齊的例子,我們可以為提示框中的數值部分加上 °C 和 ml 的字尾。
tooltip: {
valueFormatter: value => value + ' ml' // or ' °C'
}
每個系列都可以根據自己的數值格式設定自己的valueFormatter
。
更靈活的磁區圓角
在 5.0 中我們為磁區新增了圓角的設定,可以讓餅圖,旭日圖變得更有趣。之前圓角的設定只支援內半徑和外半徑分開設定,這次我們更進一步,支援磁區的四個角都設定成不同的圓角大小,帶來更靈活的呈現。
餅圖的複雜標籤優化
餅圖一直是 ECharts 中標籤呈現最複雜的圖表之一,我們從 5.0 開始就一直在餅圖的標籤佈局、顯示上做了很多的優化。
這次我們針對使用了換行,背景色,富文字等格式比較複雜的餅圖示籤做了深度的優化。在寬度的自適應、超出容器、引導線的計算上比之前有了更好的效果:
柱狀圖 large 模式優化
在資料量很多(> 2k)的時候,我們支援柱狀圖通過開啟 large 模式來加速渲染,提升互動效能,但是之前 large 模式下對柱狀圖佈局比較簡單,不支援多系列堆疊後的佈局。在 5.3.0 中我們對 large 模式的佈局進行了優化,跟普通模式保持了一致性。我們可以在更多的場景中通過開啟 large 來優化柱狀圖的效能。
除此之外,優化後的柱狀圖佈局也修復了在對數軸這樣的非線性軸上堆疊效果不正確的 bug。
非相容改動
registerMap 和 getMap 方法需要在引入地圖元件後才能使用
為了減少最小打包的體積,我們從核心模組中移除了地圖資料管理的方法getMap
和registerMap
。
如果你是 ECharts 元件的話,需要保證先引入了GeoComponent
或者MapChart
之後,才能使用registerMap
註冊地圖資料。
import * as echarts from 'echarts/core';
import { MapChart } from 'echarts/charts';
echarts.use([MapChart]);
// 必須在使用 use 方法註冊了 MapChart 後才能使用 registerMap 註冊地圖
echarts.registerMap('world', worldJSON);
如果你是使用import * as echarts from 'echarts'
全量引入,這次改動不會對你產生任何影響。
折線圖移除預設高亮加粗的效果
我們在 5.0 裡對摺線圖引入了預設高亮加粗的效果,但是社群反饋這個在很多場景效果並不好,所以在這個版本我們將這個效果從預設開啟改為預設關閉,如果需要使用高亮加粗,則可以顯示設定:
series = {
type: 'line',
//...
emphasis: {
lineStyle: {
width: 'bolder'
}
}
};