JavaScript C3.js

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

許智庭 Tim Hsu 2022/01/07 14:32:09
1226

本文使用資源

axios

API 連結

本文重點

使用 axios 串接 API,並且使用 forEach 來選取所要的資料,並且這次透過 change 事件的判斷條件,使資料有排序功能。

陣列排序進度

axios 取得 API 資料

 

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

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

 

建立清單渲染於網頁

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

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

 

目前進度可看連結

 

監聽切換排序功能

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

select

 

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

 

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

 

sort() 排序資料

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

  • 建立一個函式,其參數為(資料,select 選擇結果)。
  • 判斷 select 的結果是 id ,使資料採用 sort()方法做排序(小到大),因為取得的值為字串,所以同時轉型為整數。
  • 判斷 select 的結果是 process,使資料採用 sort()方法做排序(大到小),並只取到小數點後兩位,因後台結果有超過小數點兩位,小數點取到後兩位的渲染畫面較好看也可以做區別。
//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,其函式內容要按照原本條件的順序排列,不然讀取的結果會是相反。(因為程式是由上到下讀取)

 

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

點連結看目前進度

 

串接 C3 圖表

起手式

基本認識可以看好用的輕量統計圖表 C3.js

取得資料

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

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

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

 

來看一下函式內容。

資料排序

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

  • 資料排序從完成率高到低。
  • 取得完成率資料,取得小數點後兩位,並用百分比顯示,增加到圖表中的 columns
  • 將參賽者姓名資料,增加到 category 的空陣列中。
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 為要帶入的標籤內容與位置。

更多設定可以參考官網範例

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

許智庭 Tim Hsu