新聞中心
什么是 ECharts 自定義系列?
自定義系列(custom series)是一種系列的類型,它能夠讓用戶定制渲染邏輯,在已有的坐標系中創(chuàng)造新的圖表;并且增強了極坐標柱狀圖、自定義維度映射、dataZoom 等 。

自定義系列(custom series)它把繪制圖形元素這一步留給開發(fā)者去做,從而開發(fā)者能在坐標系中自由繪制出自己需要的圖表。
ECharts 為什么會支持自定義系列?
由于圖表的類型多種多樣,要讓 ECharts 內(nèi)置支持所有類型的圖表是很難的,有很多小眾的需求 ECharts 并不能內(nèi)置的支持。那么就需要提供一種方式來讓開發(fā)者自己擴展。另一方面,所提供的擴展方式要盡可能得簡單,例如圖形元素創(chuàng)建和釋放、過渡動畫、tooltip、數(shù)據(jù)區(qū)域縮放(dataZoom)、視覺映射(visualMap)等功能,盡量在 ECharts 中內(nèi)置得處理,使開發(fā)者不必糾結于這些細節(jié)。綜上考慮形成了 自定義系列(custom series)。
例如,下面的例子使用自定義系列( custom series)擴展出了 x-range 圖:
點擊編輯實例 》》
下面來介紹開發(fā)者怎么使用自定義系列(custom series)。
(一)renderItem 方法
通過書寫 renderItem 函數(shù)能夠讓開發(fā)者實現(xiàn)自定義的圖形元素渲染邏輯,例如:
var option = {
...,
series: [{
type: 'custom',
renderItem: function (params, api) {
// ...
},
data: data
}]
}在渲染階段,對于 series.data 中的每個數(shù)據(jù)項(為方便描述,這里稱為 dataItem),會調用此 renderItem 函數(shù)。
renderItem 函數(shù)的作用:返回一個(或者一組)圖形元素定義,圖形元素定義了圖形元素的類型、位置、尺寸、樣式等。
ECharts 會根據(jù)這些 圖形元素定義 來渲染出圖形元素。如下述所示:
var option = {
...,
series: [{
type: 'custom',
renderItem: function (params, api) {
// 對于 data 中的每個 dataItem,都會調用這個 renderItem 函數(shù)。
// (但是注意,并不一定是按照 data 的順序調用)
// 這里進行一些處理,例如,坐標轉換。
// 這里使用 api.value(0) 取出當前 dataItem 中第一個維度的數(shù)值。
var categoryIndex = api.value(0);
// 這里使用 api.coord(...) 將數(shù)值在當前坐標系中轉換成為屏幕上的點的像素值。
var startPoint = api.coord([api.value(1), categoryIndex]);
var endPoint = api.coord([api.value(2), categoryIndex]);
// 這里使用 api.size(...) 獲得 Y 軸上數(shù)值范圍為 1 的一段所對應的像素長度。
var height = api.size([0, 1])[1] * 0.6;
// 這里返回為這個 dataItem 構建的圖形元素定義。
return {
// 表示這個圖形元素是矩形。還可以是 'circle', 'sector', 'polygon' 等等。
type: 'rect',
// shape 屬性描述了這個矩形的像素位置和大小。
// 其中特殊得用到了 echarts.graphic.clipRectByRect,意思是,
// 如果矩形超出了當前坐標系的包圍盒,則剪裁這個矩形。
shape: echarts.graphic.clipRectByRect({
// 矩形的位置和大小。
x: startPoint[0],
y: startPoint[1] - height / 2,
width: endPoint[0] - startPoint[0],
height: height
}, {
// 當前坐標系的包圍盒。
x: params.coordSys.x,
y: params.coordSys.y,
width: params.coordSys.width,
height: params.coordSys.height
}),
// 用 api.style(...) 得到默認的樣式設置。這個樣式設置包含了
// option 中 itemStyle 的配置和視覺映射得到的顏色。
style: api.style()
};
},
data: [
[12, 44, 55, 60], // 這是第一個 dataItem
[53, 31, 21, 56], // 這是第二個 dataItem
[71, 33, 10, 20], // 這是第三個 dataItem
...
]
}]
}renderItem 函數(shù)中包含兩個參數(shù):
- params:包含了當前數(shù)據(jù)信息(如 seriesIndex、dataIndex 等等)和坐標系的信息(如坐標系包圍盒的位置和尺寸)。
- api:是一些開發(fā)者可調用的方法集合(如 api.value()、api.coord())。
renderItem 函數(shù)須返回根據(jù)此 dataItem 繪制出的圖形元素的定義信息,參見 renderItem.return。
一般來說,renderItem 函數(shù)的主要邏輯,是將 dataItem 里的值映射到坐標系上的圖形元素。這一般需要用到 renderItem.arguments.api 中的兩個函數(shù):
- api.value(...),意思是取出 dataItem 中的數(shù)值。例如 api.value(0) 表示取出當前 dataItem 中第一個維度的數(shù)值。
- api.coord(...),意思是進行坐標轉換計算。例如 var point = api.coord([api.value(0), api.value(1)]) 表示 dataItem 中的數(shù)值轉換成坐標系上的點。
有時候還需要用到 api.size(...) 函數(shù),表示得到坐標系上一段數(shù)值范圍對應的長度。
返回值中樣式的設置可以使用 api.style(...) 函數(shù),他能得到 series.itemStyle.normal 中定義的樣式信息,以及視覺映射的樣式信息。也可以用這種方式覆蓋這些樣式信息:api.style({fill: 'green', stroke: 'yellow'})。
renderItem 方法寫完后,我們就完成了自定義系列 90% 的工作,接下來該對工作進行優(yōu)化了。
(二)使坐標軸的范圍自適應數(shù)據(jù)范圍
直角坐標系(grid)和極坐標系(polar)中的坐標軸的刻度范圍需要自適應當前顯示出的數(shù)據(jù)的范圍,否則繪制出的圖形會超出去。
例如,在直角坐標系(grid)中,開發(fā)者如果使用自定義系列的話,就需要設定,data 中的哪些維度會對應到 x 軸上,哪些維度會對應到 y 軸上。
上述內(nèi)容通過 encode 來設定。例如:
option = {
series: [{
type: 'custom',
renderItem: function () {
...
},
encode: {
// data 中『維度1』和『維度2』對應到 X 軸
x: [1, 2],
// data 中『維度0』對應到 Y 軸
y: 0
},
data: [
// 維度0 維度1 維度2 維度3
[ 12, 44, 55, 60 ], // 這是第一個 dataItem
[ 53, 31, 21, 56 ], // 這是第二個 dataItem
[ 71, 33, 10, 20 ], // 這是第三個 dataItem
...
]
}]
};
(三)設定 tooltip
當然,使用 tooltip.formatter 可以任意定制 tooltip 中的內(nèi)容。
但是,還有更簡單的方法,即通過 encode 和 dimensions 來設定:
option = {
series: [{
type: 'custom',
renderItem: function () {
...
},
encode: {
x: [1, 2],
y: 0,
// 表示『維度2』和『維度3』要顯示到 tooltip 中。
tooltip: [2, 3]
},
// 表示給『維度2』和『維度3』分別取名為『年齡』和『滿意度』,顯示到 tooltip 中。
dimensions: [null, null, '年齡', '滿意度'],
data: [
// 維度0 維度1 維度2 維度3
[ 12, 44, 55, 60 ], // 這是第一個 dataItem
[ 53, 31, 21, 56 ], // 這是第二個 dataItem
[ 71, 33, 10, 20 ], // 這是第三個 dataItem
...
]
}]
};
(四)其他注意事項
(1)與 dataZoom 結合使用的時候,常常使用會設置 dataZoom.filterMode 為 'weakFilter'。這個設置的意思是:當 dataItem 部分超出坐標系邊界的時候,dataItem 不會整體被過濾掉。例如:
option = {
dataZoom: {
xAxisIndex: 0,
filterMode: 'weakFilter'
},
series: [{
type: 'custom',
renderItem: function () {
...
},
encode: {
// data 中『維度1』和『維度2』對應到 X 軸
x: [1, 2],
y: 0
},
data: [
// 維度0 維度1 維度2 維度3
[ 12, 44, 55, 60 ], // 這是第一個 dataItem
[ 53, 31, 21, 56 ], // 這是第二個 dataItem
[ 71, 33, 10, 20 ], // 這是第三個 dataItem
...
]
}]
};在上述例子中,維度1和維度2對應到 X 軸,dataZoom 組件控制 X 軸的縮放。
假如在縮放的過程中,某個 dataItem 的維度1超出了 X 軸的范圍,維度2還在 X 軸的范圍中,那么只要設置 dataZoom.filterMode = 'weakFilter',這個 dataItem 就不會被過濾掉,從而還能夠使用 renderItem 繪制圖形(可以使用上面提到過的 echarts.graphic.clipRectByRect 把圖形繪制成被坐標系剪裁過的樣子)。參見上面提到過的例子:Profile
(2)此外,開發(fā)者還應注意,renderItem.arguments.params 中的 dataIndex 和 dataIndexInside 是有區(qū)別的:
- dataIndex 指的 dataItem 在原始數(shù)據(jù)中的 index。
- dataIndexInside 指的是 dataItem 在當前數(shù)據(jù)窗口(參見 dataZoom)中的 index。
renderItem.arguments.api 中使用的參數(shù)都是 dataIndexInside 而非 dataIndex,因為從 dataIndex 轉換成 dataIndexInside 需要時間開銷。
參考閱讀
更多的自定義系列的例子參見:custom examples
分享題目:創(chuàng)新互聯(lián)ECharts教程:ECharts自定義系列
標題鏈接:http://www.dlmjj.cn/article/dhopjep.html


咨詢
建站咨詢
