iT邦幫忙

2021 iThome 鐵人賽

DAY 5
0
  • Sorting

大多時候我們對於資料感興趣在極端值的區域,也最邊緣的最大或最小的前幾名,而我們可以用排序的功能使它們列於表格的最上方。這個同樣在架構上可以參考W3Schools的範例,但其中演算法和機制我們加以改良。

  • Implement

首先是排序的主體,我們選用bubble的方式來實現,這可以參考此範例,其中我們以rows[i].getElementsByTagName("td")[colIndex].innerHTML來抓取當下這一個元素以及用rows[i + 1].getElementsByTagName("td")[colIndex].innerHTML來抓取相鄰的下一個元素,而innerHTML抓出的結果會是string,所以我們用個額外的function將如果是number的轉成number。
若想要由小到大排列時,但當下元素若大於下一個元素,則需交換這兩個元素的位置,反之若為由大到小亦然,此時再用parentNode.insertBefore此function來互換位置。
第二個比較特別的功能是,我們可以讓由大到小(dir="desc")以及由小到大(dir="asc")在點表頭時做切換。作法為預設由大到小,若序列已經是由大到小,則改為由小到大再重複一次流程:

function sortTable(tableId, colIndex) {
  let i, currContent, nextContent, shouldSwitch = 0;
  let table = document.getElementById(tableId);
  let rows = table.rows;
  let switching = true;
  let dir = "desc";
  let fullRowLength = rows.length - 1;
  let rowLength = fullRowLength
  // Make a loop that will continue until no switching has been done:
  while (switching) {
    // Start by saying: no switching is done:
    switching = false;
    /* Loop through all table rows (except the first, which contains table headers): */
    for (i = 1; i < rowLength; i++) {
      shouldSwitch = false;
      // Get the two elements you want to compare, one from current row and one from the next:
      // if case-insensitive, add toLowerCase()/toUpperCase()
      currContent = stringToNumber(rows[i].getElementsByTagName("td")[colIndex].innerHTML);
      nextContent = stringToNumber(rows[i + 1].getElementsByTagName("td")[colIndex].innerHTML);
      /* Check if the two rows should switch place, based on the direction, asc or desc: */
      if (dir == "asc") {
        if (currContent > nextContent) {
          shouldSwitch = true;
        }
      } else if (dir == "desc") {
        if (currContent < nextContent) {
          shouldSwitch = true;
        }
      }
      if (shouldSwitch) {
        /* If a switch has been marked, make the switch
        and mark that a switch has been done: */
        rows[i].parentNode.insertBefore(rows[i + 1], rows[i]);
        switching = true;
      }
    }
    /* If no switching has been done AND the direction is "asc",
    set the direction to "desc" and run the while loop again. */
    if (!switching && dir == "desc" && rowLength == fullRowLength) {
      dir = "asc";
      switching = true;
    } else {
      rowLength --;
    }
  }
}

接下來是HTML的部分,我們需要在表頭()的屬性中,加上點了會觸發(onclick)來呼叫剛所寫的sortTable,在之前day2所寫的生成表格的function也可以更新加入這個功能(註解為原本code),而那時留下的keyName這個伏筆的變數就是這時用的,可以給入對應表格的id:

// content += "<th>" + cell + "</th>";
content += "<th onclick=\"sortTable(\'" + keyName + "\', " + count_cell + ")\">" + cell + "</th>" ;

最後一樣是今日結果:
數學由大到小排序:
https://ithelp.ithome.com.tw/upload/images/20210906/20141158Y8jxWFNn0d.jpg
數學由小到大排序:
https://ithelp.ithome.com.tw/upload/images/20210906/20141158BsdaSwZ4Mc.jpg
程式由大到小排序:
https://ithelp.ithome.com.tw/upload/images/20210906/20141158lh1lJkvpJB.jpg
程式由小到大排序:
https://ithelp.ithome.com.tw/upload/images/20210906/20141158a1WhucKpZc.jpg
等我研究完怎麼上傳動畫再更新。


上一篇
Day4 Are you my destiny?
下一篇
Day6 我承認我是視覺動物
系列文
以網頁呈現資料視覺化30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言