0%

JSP 筆記 - 陣列排序 Sort()與 C3.js 視覺資料處理

c3

JSPJavaScript Special Practice (JavaScript 特別訓練),這是在六角學院這次長達六十天的特訓,學員專屬,這名字是我自己取的,覺得相當帥氣中二

之前學習到如何使用 axios 串接 AJAX,並且使用 forEach 來選取所要的資料,並且這次透過 change 事件的判斷條件,使資料有排序功能。

本次練習使用此 API。連結

陣列排序進度

axios 取得 API 資料

  • 綁定 HTML 的標籤,變數也使用一樣的名稱。
  • 宣告一個變數為 data,後續存放回傳的資料用。
  • 使用 axios 取得 API 資料。
1
2
3
4
5
6
7
8
let record = document.querySelector(".record");
let data;

axios.get(dataUrl).then((response) => {
data = response.data;
console.log(data);
getRecord();
});

建立清單渲染於網頁

使用一個函式存放要取得資料的方式,

  • 宣告一個變數為空字串。
  • 透過 forEach 來取得想要的資料。
  • 組字串,因為我要做成列表,所以用一個 div 包住,成為區塊元素。
  • 用 innerHTML 印出標籤在網頁上。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function getRecord() {
let str = "";
data.forEach((item) => {
str += `
<div>
<ul>
<li>${item.name}</li>
<li>${item.process}</li>
</ul>
</div>
`;
});
record.innerHTML = str;
}

CodePen https://codepen.io/tim_hsu/pen/QWyVWrR?editors=0010

監聽切換排序功能

延續上方取得資料後,要使用一個下拉選單做為條件,並排序其資料內容。

select

把選項先寫好在 option 中,並在 select 做一個 class。

1
2
3
4
<select class="select">
<option value="id">依照 id 編號排序(由1開始從上往下)</option>
<option value="process">依照完課率排序(由最高到最低)</option>
</select>

sort() 排序資料

使用 sort() 讓資料可以依照條件排序:

  • 建立一個函式,其參數為(資料,select 選擇結果)。
  • 判斷 select 的結果是 id ,使資料採用 sort()方法做排序(小到大),因為取得的值為字串,所以同時轉型為整數。
  • 判斷 select 的結果是 process,使資料採用 sort()方法做排序(大到小),並只取到小數點後兩位,因後台結果有超過小數點兩位,小數點取到後兩位的渲染畫面較好看也可以做區別。
1
2
3
4
5
6
7
//select 排列條件
function sortData(data, select) {
if (select === "id") data.sort((x, y) => parseInt(x.id) - parseInt(y.id));
//四捨五入,取小數點後兩位
else if (select === "process")
data.sort((x, y) => parseFloat(y.process) - parseFloat(x.process));
}

監聽事件

完成資料處理後,建立 select 的監聽事件,對應的是 change,其函式內容要按照原本條件的順序排列,不然讀取的結果會是相反。(因為程式是由上到下讀取)

1
2
3
4
5
6
//順序要擺對,不然內容會錯
function selectRecord() {
sortData(data, select.value);
getRecord();
}
select.addEventListener("change", selectRecord);

CodePen https://codepen.io/tim_hsu/pen/BajOyRB?editors=1010

串接 C3 圖表

起手式

基本認識可以看C3.js 基本認識

取得資料

延續前面所使用的 sort()axios 方法,結合 C3.js 圖表套件完成視覺化資料處理。

  • 宣告 columns 變數要放入完成率的資料。
  • 宣告 category 變數要放入參賽者姓名資料。
  • 其中要執行兩個函式。
1
2
3
4
5
6
7
8
9
let data; //存放回傳資料用
let columns = ["完成率"]; //data 對應名稱與存放數據資料用
let category = []; //參賽者姓名資料

axios.get(dataUrl).then((response) => {
data = response.data;
sortData(data);
load(columns, category);
});

來看一下函式內容。

資料排序

改寫之前的篩選排序方法,

  • 資料排序從完成率高到低。
  • 取得完成率資料,取得小數點後兩位,並用百分比顯示,增加到圖表中的 columns
  • 將參賽者姓名資料,增加到 category 的空陣列中。
1
2
3
4
5
6
7
function sortData(data) {
data.sort((x, y) => parseFloat(y.process) - parseFloat(x.process)); //完成率資料排序,高到低
data.forEach((item) => {
columns.push(parseFloat(item.process) / 100); //完成率資料取得小數點後兩位後,變百分比呈現
category.push(item.name); //把參賽者資料推到參數中
});
}

呈現在視覺資料中

  • 函式要帶入的參數就是完成率與參賽者資料。
  • columns 就是把宣告的變數項目與完成率資料展開放在一起。
  • colors 的屬性要與 columns 所帶入的 data 名稱相符,這邊為完成率,顏色使用色票,並使用字串形式。
  • size 的屬性設定圖表高度 *30px,不然會全部擠在一起,無法辨識。
  • axis 屬性增加 rotated 的原因是資料太多,改成橫向較好閱讀(所以 X 軸變成 Y 軸位置)。
  • categories 屬性帶入的就是宣告的參賽者變數 category。
  • label 為要帶入的標籤內容與位置。

    更多設定可以查看官網 Reference

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
function load(columns, category) {
var chart = c3.generate({
bindto: "#chart",
data: {
columns: [
[...columns], //完成率與資料展開
],
axes: {
完成率: "y2",
},
type: "bar", //圖表類型
colors: {
完成率: "#9CCC65",
},
},
size: {
height: category.length * 30, //調整圖表高度
},
axis: {
rotated: true, //轉成橫向
x: {
type: "category", // 左側 X 軸顯示
categories: category, //參賽姓名資料
label: {
text: "參賽者姓名",
position: "outer-center",
},
},
y: {
show: true, //下方 Y 軸顯示
label: {
text: "完成率%",
position: "outer-middle", //名稱位置
},
},
y2: {
show: true, //上方 Y 軸顯示
label: {
text: "完成率%",
position: "outer-middle", //名稱位置
},
},
},
});
}

Demo https://codepen.io/hnzxewqw/full/BajOvob