題目

HackMD - Collaborative Markdown Knowledge Base

作業練習

目前進度

D3.js、C3.js 資料視覺化教學

//基本上完全按照TimHsu的架構
//下方放29關的選單和表格
//資料格式從parseFloat改為parseInt
allData.sort((a, b) => {
   return parseInt(b.process) - parseInt(a.process);
});

//c3.js的設定
colors: {
    '完成率': function (d) {
     // console.log(d.value);//要使用漸層色,必須是整數
    return '#' + (0xff0000 + (d.value - 1000) * 256 * 3).toString(16);
  }
},
//把篩選改成使用seclect的value選項
if (select === 'id') {
        allData.sort((a, b) => { //從大到小排序
            return parseInt(a.id) - parseInt(b.id);
        });
    } else if (select === 'process') {
        allData.sort((a, b) => {
            return parseInt(b.process) - parseInt(a.process);
        });
    } else {
        return;
 }

//人數太多,存放資料時去除0%的資料
allData.forEach(item => {
     if (item.process !== '0%') { //去除0%
         columns.push(parseInt(item.process)); //完成率資料
         category.push(item.name);
     } else {
         return;
     }
 })

//刪除起始畫面,改為選單控制
axios.get(url).then(res => {
    allData = res.data;
    // console.log(allData);
    //預設為空白畫面
}).catch(err => {
    console.log(err);
})

//加上選單的控制監聽
let sortSelect = () => { //清空資料再切換選單
    columns = ['完成率'];
    category = [];
    sortData(allData, select.value);
    allList();
}
select.addEventListener('change', sortSelect, false)

//在渲染畫面加上呼叫繪製圖表的方訊
load(columns, category);

// let allNum = document.querySelector('.allNum'); //上方數量計算
let list = document.querySelector('.list'); //排序畫面
let select = document.querySelector('#select'); //下拉選單
let url = '<https://raw.githubusercontent.com/hexschool/hexschoolNewbieJS/master/data.json>';
let allData = [];
let columns = ['完成率'] //存放數據資料用
let category = []; //學員名稱

axios.get(url).then(res => {
    allData = res.data;
    // console.log(allData);
    //預設為空白畫面
}).catch(err => {
    console.log(err);
})

let allList = () => { //下方列表畫面
    let text = '';
    allData.forEach(allId => {
        if (allId.process !== '0%') {  //去除0%
            text += `<tr>
        <td>-</td>
        <td>${allId['id']}</td>
        <td>${allId['name']}</td>
<td class = "w-50 p-3" >
<div class = "progress" style = "height: 24px;" >
<div class = "progress-bar bg-success" role = "progressbar" style = "width:${allId.process}"  aria-valuemin = "0" aria-valuemax = "100">${allId.process}</div>
</div>
        </td></tr>`
        } else {
            return;
        }
    });
    list.innerHTML = text;
    load(columns, category); //繪製圖表
}

//加上C3.js圖表
let sortData = (data, select) => { //使用parseInt而非parseFloat是為了使用漸層色
    if (select === 'id') {
        allData.sort((a, b) => { //從大到小排序
            return parseInt(a.id) - parseInt(b.id);
        });
    } else if (select === 'process') {
        allData.sort((a, b) => {
            return parseInt(b.process) - parseInt(a.process);
        });
    } else {
        return;
    }

    allData.forEach(item => {
        if (item.process !== '0%') { //去除0%
            columns.push(parseInt(item.process)); //完成率資料
            category.push(item.name);
        } else {
            return;
        }
    })
}

function load(columns, category) {
    var chart = c3.generate({
        bindto: "#chart",
        data: {
            columns: [
                [...columns], //完成率與資料展開
            ],
            axes: { //增加第2個Y軸
                完成率: "y2",
            },
            type: "bar", //圖表類型
            colors: { //屬性須和columns所帶入的資料名稱相同,完成率'
                // 完成率: "#9CCC65",
                '完成率': function (d) {
                    // console.log(d.value);//要使用漸層色,必須是整數
                    return '#' + (0xff0000 + (d.value - 1000) * 256 * 3).toString(16);
                }
            },
        },
        size: {
            height: category.length * 15, //調整圖表高度
            // height: 800
        },
        axis: {
            rotated: true, //轉成橫向
            x: {
                show: true,
                type: "category", // 左側 X 軸顯示
                categories: category, //參賽姓名資料
                label: {  //要帶入的標籤內容和位置
                    text: "參賽者姓名",
                    position: "outer-center",
                },
            },
            y: {
                show: true, //下方or左側 Y 軸顯示
                label: {
                    text: "完成率",
                    position: "outer-middle", //名稱位置
                },
            },
            y2: {
                show: true, //上方or右側 Y 軸顯示
                label: {
                    text: "完成率%",
                    position: "outer-middle", //名稱位置
                },
            },
        },
    });
}
let sortSelect = () => { //清空資料再切換選單
    columns = ['完成率'];
    category = [];
    sortData(allData, select.value);
    allList();
}
select.addEventListener('change', sortSelect, false)
<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>030</title>
    <link href="<https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.18/c3.css>">
    <link rel="stylesheet" href="<https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css>">

    <style>
        body {
            font-family: "微軟正黑體";
        }

        .allSelect,
        .allNum {
            margin-top: 1%;
            display: flex;
            justify-content: center;
        }

        .allNum {
            font-size: 24px;
        }

        #chart {
            margin-top: 1%;
        }
    </style>
</head>

<body>
    
    <div class="container">
        <div class="allSelect">
            <select name="" id="select" class="form-control">
                <option value=""> ----- 請選擇 ----- </option>
                <option value="id">編號(id)排序(由1開始從上往下)</option>
                <option value="process">完課率(process)排序(由高到低)</option>
                <!-- <option value="name">姓名(name)排序</option>
                <option value="same">相同名次排序</option> -->
            </select>
        </div>
        <div id="chart"></div>
        <div class="allNum"></div>
        <table class="table table-hover">
            <thead class="thead-dark">
                <tr>
                    <th scope="col">名次</th>
                    <th scope="col">編號</th>
                    <th scope="col">姓名</th>
                    <th scope="col">完成度</th>
                </tr>
            </thead>
            <tbody class="list"></tbody>
        </table>
    </div>
    <script src="<https://cdnjs.cloudflare.com/ajax/libs/d3/5.16.0/d3.js>"></script>
    <script src="<https://cdnjs.cloudflare.com/ajax/libs/c3/0.7.18/c3.js>"></script>
    <script src="<https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js>"></script>
    <script src="030.js"></script>
</body>

</html>

codpen

https://codepen.io/sesame55/pen/oNbJxbq