avatar

目錄
Project - New Labor Pension Fund

新制勞工退休基金經營概況

Demo

前言

在政府資料開放平臺逛到投資理財類別時,看到新制勞工退休基金每月收益。前段時間,新聞總是提到新制勞工退休基金這幾個月的收益不錯,加上我之前也有自提退休金,就好奇這幾個月的收益到底有多好。由於這些資料直接看並不直覺,於是決定將它畫成圖表,連同相關資訊一起觀察。

簡介

藉由視覺化的方式觀察:

  • 新制勞工退休基金近一年來每個月的操作收益率與保證收益率。
  • 新制勞工退休基金歷年的操作收益與保證收益。
  • 新制勞工退休基金投資的股票類型以及投資比例。

資料來源

資料取自於政府資料開放平臺,搜尋關鍵字為 「勞工退休基金」。

使用工具或技術

  • Bootstrap
  • jQuery
  • Chart.js
  • skrollr

過程

因為這次的練習主要在 API 的串接,所以使用 Bootstrap 來排版跟架構內容,搭配 jQuery 使用 AJAX ,再以 Chart.js 繪製圖形讓資料視覺化,最後用 skrollr 加上一點視差滾動效果,讓頁面不至於太過單調。

進行到畫表格的時候,琢磨了一下 jQuery 動態產生表格的程式碼該怎麼寫,畢竟表格用到的標籤多,而且各有其功能與意義。想到之前曾看過別人做九九乘法表的表格,就去找來看撰寫邏輯,這才將思路理清。

接著將 AJAX 載入的資料用 Chart.js 繪製出來。由於這是我第一次用 Chart.js,閱讀了 Chart.js 官方文件,以及其他開發者用 AJAX 取得的資料繪製 Chart.js 圖形的紀錄文章,歸納執行步驟如下:

  1. 先引用 Chart.js 的 CDN
  2. 在 HTML 加上 canvas 定義圖形位置
  3. 在 JavaScript 使用 AJAX 取得資料
  4. 透過 for 迴圈將取得的資料推到建立的空陣列中 (X 軸標籤、折線圖資料)
  5. 取得 Canvas 的內容
  6. 建構圖表、將資料指派到對應位置,並設置圖表的各項屬性與值

不過,範例都是一組資料,也就是說,折線圖中只有一條線,但我想放兩組資料,產生兩條線去互相比較、看走向,在官方文件中卻沒找到,一時不知道該從哪裡下手。

後來看到 Chart.js Samples 的範例中有兩條線的折線圖,去找了 GitHub 內對應的程式碼來看,才明白如果要在裡面放兩組資料,只要在 datasets 中用陣列放兩組物件,分別設置資料即可。

節錄部分程式碼整理如下:

javascript
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
$.ajax({
url: "url",
success: function (res) {
var responseData = res.result.records;
var labels = [];
var dataset1 = [];
var dataset2 = [];

// 將取得的資料推入陣列
for (var i = 0; i < responseData.length; i++) {
var month = responseData[i].月別;
var rateOfInvestment = responseData[i].收益率;
var rateOfGuarantee = responseData[i].保證收益率;
labels.push(month);
dataset1.push(rateOfInvestment);
dataset2.push(rateOfGuarantee);
}

// 繪製折線圖
var ctx = $("#chartForNewByMonth");
var chart = new Chart(ctx, {
type: "line",
data: {
labels: labels,
datasets: [{
label: "收益率",
data: dataset1,
borderColor: "#1769ff",
fill: false
}, {
label: "保證收益率",
data: dataset2,
borderColor: "#70b29c",
fill: false
}]
},
options: {
responsive: true,
}
})
}
});

繪製第三部分國內投資股票時,因為資料筆數多,表格不好呈現,所以只顯示折線圖。為了更好看出這些股票的投資比例高低,在繪製之前先將取得的資料進行了排序,然後才繪製圖形。

最後,因為覺得整體過於單調,所以用 skrollr 加上一點視差滾動效果。但滑鼠滾著滾著卻發現,只有「每月經營概況」那邊有反應,「年度經營概況」跟「股票類別」沒反應。

因為查了一陣子仍然看不出問題在哪裡,就到臉書的前端社團詢問。才知道這是因為在 AJAX 拿到資料繪製圖表之前,skrollr 已經完成 scroll 事件綁定,這時候 DOM 還沒有圖表的元素及高度。如果要解決這個問題,在每個 AJAX 繪圖之後加上 s.refresh() 就能看到效果了。

在這之前,有網友回饋視窗大小變化後,「年度經營概況」跟「股票類別」就會有反應。會這樣是因為視窗縮放時,skrollr 會重新計算高度,並且呼叫 refresh API。

問題與解決

製作這個作品時,我遇到的問題及解決方式整理如下:

問題一: jQuery 怎麼動態產生表格

進行到畫表格的時候,因為表格用到的標籤多,而且各有其功能與意義。所以怎麼用 jQuery 動態產生表格讓我思索了一番。

後來想起,之前曾看過別人做九九乘法表的表格,就去找來看撰寫邏輯,這才將思路理清,順手也做了一個九九乘法表出來。

參考: JavaScript與jQuery網頁設計範例教本 (電子書)

問題二:如何用 AJAX 取得的資料繪製 Chart.js 折線圖

第一次用 Chart.js 繪圖,所以去找官方文件研究其安裝跟使用方式。不過,官方範例中使用的圖形資料都是寫死的,而且只有一條線。但我希望政府資料開放平臺上的資料更新時,我的網頁上的圖形跟資料能透過 AJAX 隨之改變,而且裡面可以放兩組資料進去觀察。

查了幾篇其他開發者的文章後,看到最簡單的方式是先建立空陣列,用 for 迴圈將資料依序推進去,然後再將這些陣列放到 Chart.js 對應的位置。

再來要解決放兩組資料的問題,我在 Chart.js Samples 看到範例中有兩條線的折線圖,去找了 GitHub 內對應的程式碼來看,才明白如果要在裡面放兩組資料,只要在 datasets 中用陣列放兩組物件,分別設置資料即可。

參考:

問題三:將投資股票依比重大小排序

繪製第三部分國內投資股票時,原本的資料順序是依股票類型排序的,但這樣一來,除了電子產業、金融產業,以及塑膠工業較為明顯之外,其他的股票類型難以一眼看出比例多寡。

為了更輕易看出這些股票的投資比例高低,我在繪圖之前先將取得的資料依投資比例排序。不過因為資料比較多層,一時轉不過來要怎麼將這些資料排序。

後來發現是我想得太複雜了,同樣用 sort() 搭配函式即可。只不過進行判斷時,要帶上想排序的屬性名稱,這樣就能比較那個屬性的值了。

範例:

javascript
1
2
3
var rank = scores.sort(function(a,b){
return a.score < b.score ? 1 : -1
})

參考: JavaScript 陣列元素順序重新排序 sort()

問題四:skrollr 無法正常呈現效果

加上 skrollr 後使用發現,只有「每月經營概況」那邊有視差滾動效果,「年度經營概況」跟「股票類別」沒反應。

因為查了一陣子仍然找不出問題在哪裡,就到臉書的前端社團詢問。才知道這是因為在 AJAX 拿到資料繪製圖表之前,skrollr 已經完成 scroll 事件綁定,這時候 DOM 還沒有圖表的元素及高度。如果要解決這個問題,在每個 AJAX 繪圖之後加上 s.refresh() 就能看到效果了。

去 skrollr GitHub 找了 README 文件裡,有關 refresh API 的說明來看:

refresh API

裡面提到,refresh API 會重新解析所有給定的元素,如果小括號內沒有給定元素,則再次解析文檔中所有元素。

這個 API 適合在以下幾種情況使用:

  • 當元素使用 “relative” 模式且需要被更新的時候
  • 資料屬性是動態操作的
  • 在 DOM 增加新元素,且新元素會受到 skrollr 控制

以下為蒐集到的使用 refresh API 的寫法

javascript
1
2
3
4
5
var s = skrollr.init();

//........

s.refresh($("#home-slides div"));
javascript
1
2
3
4
5
//Add one element dynamically
var newElement = $(
'
TEST
'

).appendTo('body');
s.refresh(newElement[0]);

此外,有網友回饋視窗大小變化後,「年度經營概況」跟「股票類別」就會有效果了。會這樣是因為視窗縮放時,skrollr 會重新計算高度,並且呼叫 refresh API。

參考:

後記

畫成圖表之後去看,這幾個月的收益率確實節節攀升,對於勞工們來說是福音。

每月經營概況

年度的部分可看出,較差的幾年正好逢股災,收益不好也在所難免。其它年度的收益則優於保證收益率。

年度經營概況

而透過投資股票類別能看到,新制勞工退休基金在國內投資的股票,多半集中在起伏較大的電子產業,然後是穩定的金融保險類股。

國內投資股票類別

考慮過把舊制勞退基金的資料也一起放進來,但舊制的每月收益不知為何只提供最近一個月的資料,再加上舊制歷史悠久,年度資料過多,如何呈現是個問題。其投資股票類別的比例也與新制差異不大,只有在指數股票型基金的投資比例 4.x% 相較新制的 0.2% 高很多。至於多出來的這些,主要是減少電子產業類別的比例來的。

本來想說這些資料是透過 AJAX 取得的,那麼只要政府資料開放平臺更新,這個頁面上的資料也會隨之更新、不怕過時。但是,等到次月政府資料開放平臺上的資料更新後,打開來看發現除了年度收益的資料仍在,每月收益跟股票投資類別的資料都沒有顯示出來。

到政府資料開放平臺確認後發現,次月新資料的 API 網址路徑位置和我當時取得的不同。於是,舊的不能用,新的不會來。只好改為下載 JSON 格式的檔案替代網址,以免下個月資料更新時,網頁又撈不到資料可用。

雖然政府資料開放平臺更新時,我的網頁資料無法自動隨之更新讓我覺得遺憾,但至少一開始將資料視覺化的目的有達到,也算滿足了。

文章作者: Jane Lin
文章鏈接: http://yoursite.com/2020/02/13/1581540253/
版權聲明: 本博客所有文章除特別聲明外,均採用 CC BY-NC-SA 4.0 許可協議。轉載請註明來自 JL's Coding Notes

評論