# 第三十天 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/