--- 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成的文件 ![配置項名詞圖解](https://echarts.apache.org/v4/zh/documents/asset/img/basic-concepts-overview/components.jpg) **** 初始化有兩種配置方式,本人採用第二種 ### 配置1: data 和 option 交織在一起 用起來較直觀,但資料常變動時會比較麻煩 ![配置1](https://echarts.apache.org/v4/zh/documents/asset/img/basic-concepts-overview/series-all-a.jpg) **** ### 配置2: 把 data 抽出來集中管理,在 series 中只設定對應的維度 較不直觀,但對於頻繁更動資料的情況較方便 ![配置2](https://echarts.apache.org/v4/zh/documents/asset/img/basic-concepts-overview/series-all-b.jpg) 實作時把圖表製成 component 資料從外部傳到元件內 ![方法比較](https://i.imgur.com/IH4xgjy.jpg) - **把各種 chart 類型製成 component** 優點是單支 component 複雜度低 缺點是耦合度高,適合圖表類型不多或圖表內容差異大的情況 - **只做一個 chart component,在資料傳入時帶上 chart 類型直接在元件中判斷產出哪種圖表** 優點是低耦合與外部的接口一致 缺點是元件內部變得較複雜,適合圖表類型較多且內容相似的情況 此專案目前的圖表種類差異較大,採用第一種方法程式碼比較好管理 ## example🤏 以 dashboard 的 barchart 為例: ![dashboard畫面](https://truth.bahamut.com.tw/s01/202101/6da2cb41566282e5d5ec744a49d181ab.JPG) ### 1. 父元件(dashboard.vue)從 Vue store 拿所有資料(allData) allData 都是從 API 撈回來未經處理過的數據 ![allData](https://i.imgur.com/x8YRBIN.png) ### 2. 用 computed 的方式處理 allData 並返回特定的數據 在父元件這一層處理資料然後再分發給對應的 chart component 去作呈現 dashboard 的 barchart 有資料篩選的功能 ![data filter](https://i.imgur.com/GnXQOVz.png) **以下為範例,並非實際的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])); } } ```