---
tags: bahamut-pie, side project
---
# bahamut-pie - chapter3: make pies with ECharts🥧
**本文以開發時用的4.x版為準**
ECharts 是一個功能超多的圖表插件,但也因此非常複雜
官方文件龐雜不過查起來挺方便的,如果用過其他的圖表插件,應該會熟悉一些
我用的是 vue 版本,[vue-charts](https://github.com/ecomfe/vue-echarts)
## how it work?
ECharts 圖表可以簡單分成
- 圖表與元件的配置(圖類,顏色,軸向單位...)
- 注入的資料 dataset(series)
理解元件名詞之後大概可以看懂3~5成的文件

****
初始化有兩種配置方式,本人採用第二種
### 配置1: data 和 option 交織在一起
用起來較直觀,但資料常變動時會比較麻煩

****
### 配置2: 把 data 抽出來集中管理,在 series 中只設定對應的維度
較不直觀,但對於頻繁更動資料的情況較方便

實作時把圖表製成 component 資料從外部傳到元件內

- **把各種 chart 類型製成 component**
優點是單支 component 複雜度低 缺點是耦合度高,適合圖表類型不多或圖表內容差異大的情況
- **只做一個 chart component,在資料傳入時帶上 chart 類型直接在元件中判斷產出哪種圖表**
優點是低耦合與外部的接口一致 缺點是元件內部變得較複雜,適合圖表類型較多且內容相似的情況
此專案目前的圖表種類差異較大,採用第一種方法程式碼比較好管理
## example🤏
以 dashboard 的 barchart 為例:

### 1. 父元件(dashboard.vue)從 Vue store 拿所有資料(allData)
allData 都是從 API 撈回來未經處理過的數據

### 2. 用 computed 的方式處理 allData 並返回特定的數據
在父元件這一層處理資料然後再分發給對應的 chart component 去作呈現
dashboard 的 barchart 有資料篩選的功能

**以下為範例,並非實際的code**
``` javascript
computed: {
barchartDataset() {
// 取用篩選器的條件,這邊以"資料類型"和"數值區間"為例(e.g. "觀看數" "0 ~ 1000" 的文章)
// dataType: "view", dataRangeMin: 0, dataRangeMax: 1000
const { dataType, dataRangeMin, dataRangeMax } = this.filterConfig;
// 全部的資料,開始篩選處理
let dataset = this.allData;
// 遍歷 dataset 裡面的資料,
dataset = dataset.filter((article) => {
// article 為單篇文章的數據(標題,發佈時間,觀看數,GP...)
// 用 Lodash.inRange 來判斷文章的"觀看數"是否在區間內
return _.inRange(item[dataType], dataRangeMin, dataRangeMax)
});
// 條件很多就如法炮製,層層處理(以下省略)
// 篩選完後要回傳 chart component 可以直接用的格式,參考上面提過的 ECharts 的配置方式
return [
['title', dataType],
...dataset.map((article) => [article.title, article.[dataType]])
]
// 格式如下
// [
// [ title: "觀看數" ],
// [ 文章1: 520 ],
// [ 文章2: 168 ]...
// ]
}
}
```
### 3. 把數據丟給 chart component 呈現
以下是 (bar)chart component 的程式碼
``` javascript
// 從父元件接到的資料
props: ['inputData'],
data() {
return{
// 圖表的option,參考上面提過的 ECharts 的配置方式
options: {
// 中間省略...
// 資料
dataset: {
source: this.inputData,
},
// 設定圖表種類與資料對應維度
series: [
{
type: 'bar',
encode: {
x: 0,
y: 1,
},
},
],
}
}
},
// 因應篩選器會變動,所以監聽傳入的資料,變動圖表的基本設定(Y軸名稱,Y軸最大值...)
watch: {
inputData(newData) {
this.options.dataset.source = newData;
const allData = newData.slice(1, -1);
// 設定圖表Y軸名稱,以目前的例子就是 "觀看數"
this.options.yAxis.name = newData[0][1];
// 設定圖表Y軸最大值(固定 bar 的高度,不要動態調整),找到最大的Y軸數據定為最大值
this.options.yAxis.max = Math.max(...allData.map((article) => article[1]));
}
}
```