---
# System prepended metadata

title: 最終關卡挑戰 Day5 - 後台(C3.js 圖表設計 - LV2 )
tags: [' 最終關卡挑戰 Day5 - 後台(C3.js 圖表設計 - LV2 )', JS 5組 - 2022 秋季 JS直播班]

---

---
tags: JS 5組 - 2022 秋季 JS直播班, 最終關卡挑戰 Day5 - 後台(C3.js 圖表設計 - LV2 )
title: 最終關卡挑戰 Day5 - 後台(C3.js 圖表設計 - LV2 )
---

###### tags: `JS 5組 - 2022 秋季 JS直播班` 、` 最終關卡挑戰 Day5 - 後台(C3.js 圖表設計 - LV2 )`

###### *date: 2022 / 11/ 25*


# Day5 - 後台(C3.js 圖表設計 - LV2 )

昨天我們已經完成後台訂單列表的API 串接與功能整合，今天是最終關卡挑戰的最後一天，要完成的任務是後台 **C3.js 圖表設計 - LV2** 區塊，大家一起加油吧!



### 今日挑戰目標: 後台(C3.js 圖表設計 - LV2 )
![](https://i.imgur.com/pVRHTct.jpg)



### 訂單列表 - 功能整合任務
-  後台( LV2 圖表)設計
    -  取得訂單資料
    -  整理 C3.js 圖表所需要的資料格式
    -  使用陣列方法 [sort](https://ithelp.ithome.com.tw/articles/10225733)，製作「降序」排列
       - 將全品項營收按照 「降序」排列
    -  篩選出前三名營收品項，其他 4~8 名都統整為「其它」。
    -  顯示 C3.js LV2 圖表
       - 做全品項營收比重，類別含四項，篩選出前三名營收品項，其他 4~8 名都統整為「其它」
-  功能測試
    -  測試 訂單列表功能 與 C3 圖表是否連動
        - 當點擊訂單列表功能(單筆刪除、刪除全部)，圖表是否能更新。
 

### 後台開發資源整理
 - [後台版型](https://codepen.io/hexschool/pen/WNJXgrR?editors=1010)
 - 陣列方法 [sort](https://ithelp.ithome.com.tw/articles/10225733)
 - 引入 c3.js 圖表 CDN
```html
<!-- Load c3.css -->
    <link href="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.20/c3.min.css" rel="stylesheet">
	
<!-- Load d3.js and c3.js -->
    <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.16.0/d3.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.20/c3.min.js"></script>

 ```
           

---

### shinyhung#3825
```javascript


```
### WeiJ#7376

圖表的資料集格式相信大家都了解，而這次 Lv2 部份需要額外處理只取前三名名稱，其他以`其他`的名稱顯示並加總

我的整理方式如下：

```javascript
    getApi().then(res => {
        let products = res.data.map(item => item.products).flat();
        // 這邊會取到巣狀陣列 (陣列包陣列)，有一個技巧是 flat() 可以平整化
        // flat() 完就只剩下一層陣列去包所有的物件，這邊就可以跑 reduce 來統整資料

       const product = products.map(item => [item.title, item.quantity]).reduce((acc, cur) => {
            if (acc[cur[0]]) {
                acc[cur[0]] += cur[1];
            } else {
                acc[cur[0]] = cur[1];
            }
            return acc;
        }, {});

        // 這邊會抓出產品名稱跟這筆訂單的數量當作新的陣列，再透過 reduce 相加整理，記得要抓數量，不然多個只會算 1
        // product 會長得像 {Charles 雙人床架: 2, Charles 系列儲物組合: 1, Antony 雙人床架／雙人加大: 1}
        // 不過他還是物件所以要把他轉成陣列，最快的方法就是 Object.entries() 直接轉成 [屬性,值]
        // 轉完之後再做排序，以多到少所以這邊是 b - a
        // 排序完陣列再透過 reduce 整理， index < 3 就是前三項最多的不理他直接用
        // index === 3 為第4項，所以要產生一個 其他的陣列，
        // 後面就依序把他加入其他的陣列中
        // 最後再把 dataset 餵給圖表就可以了

        dataset = Object.entries(product)
            .sort((a, b) => b[1] - a[1])
            .reduce((acc, cur, index) => {
                if (index < 3)
                    acc.push(cur);
                else if (index === 3)
                    acc.push(['其他', cur[1]]);
                else
                    acc[3][1] += cur[1];

                return acc;
            }, []);
    })
```

### charlottelee849#0366
待辦事項
- 前台優化
  
 
  - [x] 前台 API 整合  
- 後台
  
  - [x] c3-Lv2圖表  
    - 只取前三名名稱，以其他的名稱顯示並加總
  - [x] 後台 API 整合  
 
DEMO：[前台](https://char849.github.io/project-js9/#)、[後台](https://char849.github.io/project-js9/admin)
  
**前台知識點**

```JavaScript
 
```


### jimmyFang#9575
**任務清單**
- [x] **後台( LV2 圖表)設計**
     - [x] 取得訂單資料
     - [x] 整理 C3.js 圖表所需要的資料格式
     - [x] 使用陣列方法 [sort](https://ithelp.ithome.com.tw/articles/10225733)，製作「降序」排列
        - 將全品項營收按照 「降序」排列
     - [x] 篩選出前三名營收品項，其他 4~8 名都統整為「其它」
     - [x] 顯示 C3.js LV2 圖表
         - 做全品項營收比重，類別含四項，篩選出前三名營收品項，其他 4~8 名都統整為「其它」
- [x] **功能測試**
     - [x] 測試 訂單列表功能 與 C3 圖表是否連動
        - 當點擊訂單列表功能(單筆刪除、刪除全部)，圖表是否能更新。
 
  
目前進度: [前台](https://jimmyfang-ai.github.io/js-finalWork-wowoRoom/#orderInfo)、[後台](https://jimmyfang-ai.github.io/js-finalWork-wowoRoom/admin)


- **知識點分享:**
    :::spoiler **減少重複發送 ajax 請求**
	
   這邊以 [訂單相關(管理者) API](https://hexschool.github.io/hexschoolliveswagger/) 舉列來說，在 Swagger API 文件內有提到，在發送 **put 、delete** API 請求時，只要回傳**成功 200** 的狀態碼時，就會回傳一整個更新過的訂單列表。
  - **put**
  
  ![](https://i.imgur.com/8x5nRKd.jpg)
  - **delete**
  
  ![](https://i.imgur.com/CbOyMZo.jpg)

  **優點:**
  1. 是可以直接使用回傳後的更新資料，賦予到全域變數並進行畫面渲染，不用再去發送 **get orders API** 去拿新的訂單列表資料。
  2. 避免多次相同的請求打到伺服器，給伺服器造成壓力，進而限制請求次數，以 [TDX API](https://tdx.transportdata.tw/api-service/swagger) 為例。
   ![](https://i.imgur.com/7bR06Df.jpg)


  **範例程式碼(以修改訂單狀態為例)**
  ```jsx=
  // 定義資料
  let orderData = [];

  // 訂購表單 - 顯示客戶訂單列表
  function renderOrderLists(data) {
    // 顯示訂單列表資料
    orderList.innerHTML = data.map((order) => {
        //組訂購產品字串
        const orderProducts = order.products.map((product) => {
            return ` ${product.title} x ${product.quantity} <br>`;
        }).join('');

        return `
        <tr data-order-id="${order.id}">
        <td>${order.id}</td>
        <td>
            <p>${order.user.name}</p>
            <p>${order.user.tel}</p>
        </td>
        <td>${order.user.address}</td>
        <td>${order.user.email}</td>
        <td>
            <p>${orderProducts}</p>
        </td>
        <td>${timeDate(order.createdAt)}</td>
        <td>
            <button  class="btn btn-sm btn-primary"  data-order-status=${order.paid}  data-order-btn="changeStatus">${order.paid ? "已處理" : "未處理"}</button>
        </td>
        <td>
            <button type="button"  class="btn btn-sm btn-danger" data-order-btn="deleteOrder">刪除</button>
        </td>
    </tr>`
    }).join('');
   };

  // 訂購表單 - 修改全部狀態
  function   changeOrderStatus(orderId,   checkStatus) {
    api.apiUpdateOrder({
        "data": {
            "id": orderId,
            "paid": checkStatus
        }
    })
        .then((res) => {
            orderData = res.data.orders;
            // 顯示訂單列表
            renderOrderLists(orderData);
            swalMassage(`訂單編號: ${orderId} ，訂單狀態已修改!`, 'success', 800);
        })
        .catch((error) => {
            console.log(error);
        })
  };
  ```




### Judy Wei#6103
```JavaScript


```
### Mia小福#4473
```JavaScript


```
### Ringo#7583
```JavaScript


```
### yawun#0042
- 任務清單
    - [x] **後台( LV2 圖表)設計**
         - [x] 取得訂單資料
         - [x] 整理 C3.js 圖表所需要的資料格式
         - [x] 使用陣列方法 [sort](https://ithelp.ithome.com.tw/articles/10225733)，製作「降序」排列
            - 將全品項營收按照 「降序」排列
         - [x] 篩選出前三名營收品項，其他 4~8 名都統整為「其它」
         - [x] 顯示 C3.js LV2 圖表
             - 做全品項營收比重，類別含四項，篩選出前三名營收品項，其他 4~8 名都統整為「其它」
    - [x] **功能測試**
         - [x] 測試 訂單列表功能 與 C3 圖表是否連動
            - 當點擊訂單列表功能(單筆刪除、刪除全部)，圖表是否能更新
- [demo](https://linyawun.github.io/JSLiveFinal-WOWOROOM/)
- 知識點分享

### 法希娜#3206
->>完成：
一般商品顯示
購物車顯示+正確總額
購物車單筆刪除
全部刪除
加入購物車
送出訂單

->>待完成：輸入驗證/ 送出訂單後清空購物車


＊＊本次新增知識點：

（一）抓取擁有同樣class但各自不同id的元素，求個別click事件的該id
```JavaScript
const addCardBtn = document.querySelectorAll('.addCardBtn');
    addCardBtn.forEach((btn) =>{
        btn.addEventListener('click', (e) => {
        const idVal = e.target.getAttribute('id');
    })
})

```



