# 第三十天 C3.js 圖表整合 ## 問題 資料來源:https://raw.githubusercontent.com/hexschool/hexschoolNewbieJS/master/data.json 1. 請嘗試用 codepen 附上你的解答,這次的需求是「 用 c3.js 圖表顯示,看看誰的完課率最好,同時可以看出排名**」 2. 圖表不局限於上面的長條圖,也可尋找合適的圖 3. 週六日請嘗試寫一篇 blog,分享解題流程,讓其他人也可以受益 ## 介面 ``` <select id="sortMode"> <option value="id">依照 id 編號排序(由1開始從上往下)</option> <option value="process">依照完課率排序(由最高到最低)</option> </select> <div id="rankPic"></div> ``` ## 取得資料 ### axios 先定義一個變數raw儲存資料 ``` let raw; ``` 要取資料時: 由於資料來源不會更改,因此使用const 定義URL。 使用get取得資料,並使用raw儲存 ``` const url = "https://raw.githubusercontent.com/hexschool/hexschoolNewbieJS/master/data.json"; axios.get(url).then((res) => { raw = res.data; }); ``` 程式碼參考:第二十六天 https://codepen.io/pen/?template=pogZPEV ## 排序資料 資料依照完成度或編號排序,因此定義 sorting 函數 ``` function sorting(arr, mode) { data = { CompletionRate: ["完成率"], name: [] }; if (mode == "id") { arr.sort((x, y) => parseInt(x.id) - parseInt(y.id)); } else { arr.sort((x, y) => parseInt(y.process) - parseInt(x.process)); } } ``` 資料參考:JavaScript Array 陣列操作方法大全 ( 含 ES6 ) https://www.oxxostudio.tw/articles/201908/js-array.html#array_sort ## 圖表顯示 由於資料筆數多,打算使用橫條圖顯示 ### c3.js #### 格式整理 要先整理資料成 C3.js 的格式 查看c3.js文件後發現他長這樣 ``` ['data1', 30, 200, 100, 400, 150, 250], ['data2', 50, 20, 10, 40, 15, 25] ``` 為了方便識別與規劃,資料格式定義為這樣: ``` let data = { CompletionRate: ["完成率"], name: [] }; ``` 接著在sorting 的function後加入格式整理的部分 ``` function sorting(arr, mode) { data = { CompletionRate: ["完成率"], name: [] }; ..... arr.forEach(function(item,index){ data.CompletionRate.push(parseFloat(item.process)/100); data.name.push(item.name) }) } ``` #### 圖表顯示 首先參考C3.js的手冊與提姆寫程式 bindto:圖表顯示的元素空間 data:{columns:...}:圖表資料來源,使用解構賦值的方式展開 ``` function chart() { c3.generate({ bindto: "#rankPic", data: { columns: [ [...data.CompletionRate] ], axes: { "完成率": "y2" }, type: "bar" }, bar: { width: { ratio: 0.6 } }, size: { height: data.name.length*25, //調整圖表高度 }, axis: { rotated: true, x: { type: "category", // 左側 X 軸顯示 categories: data.name, label: { text: "參賽者姓名", position: "outer-center" } }, y: { show: true, //下方 Y 軸顯示 categories: data.CompletionRate, label: { text: "完成率%", position: "outer-middle" //名稱位置 } }, y2: { show: true, //上方 Y 軸顯示 categories: data.CompletionRate, label: { text: "完成率%", position: "outer-middle" //名稱位置 } } } }); } ``` 綁定select 事件監聽 ``` let mode = document.querySelector("#sortMode"); mode.addEventListener("change", function () { sorting(raw, mode.value); chart(); }); ``` 完成度排序: ![](https://i.imgur.com/JT4HRDM.png) 編號排序: ![](https://i.imgur.com/29dFnks.png) 完整程式碼:https://codepen.io/pen/?template=PoZxWbp 資料參考:C3.js https://c3js.org/samples/chart_bar.html 資料參考:提姆寫程式 https://hsuchihting.github.io/javascript/20200715/679666643/