今天要來介紹一個蠻重要的技巧,一般來說 JS 用來處理時間的套件相信大家首選都是 Moment.js ,當然筆者也是一樣,不過今天筆者並沒有要介紹 Moment.js
,今天筆者要來介紹 D3 自己做的用來處理時間的 API : d3.timeParse()
。
d3.timeParse()
是 D3 用來處理時間格式的 API ,如果要在 D3 的圖表中繪製跟時間有關的圖表都必須要利用 d3.timeParse()
先進行時間的轉換, d3.timeParse()
本身是一個 function 而且也會回傳一個 function ,寫法長得像下面這樣:
const parseTime = d3.timeParse()
parseTime(time)
常用 Moment.js
的你應該會發現好像少了什麼東西,一般來說這種處理時間的 API 應該都要帶一些參數進去才對,像 Moment.js
在設定時間時會這樣寫:
moment().format('MMMM DD YYYY, h:mm:ss a')
別急,接下來筆者要來談談 d3.timeParse()
所可以接受的參數類型,這邊筆者介紹幾個最常用的餐數:
參數 | 作用 |
---|---|
%a | 星期幾的縮寫 |
%A | 星期幾的全名 |
%b | 月份的縮寫 |
%B | 月份 |
%c | 日期時間的組合 ( 星期縮寫 + 月份縮寫 + 日期 + 時 + 分 + 秒 + 年 ) |
%d | 一個月中的哪一天 ( 01 到 31 ) |
%e | 一個月中的哪一天 ( 1 到 31 ) |
%H | 24 小時制 ( 00 到 23 ). |
%I | 12 小時制 ( 01 到 12 ). |
%j | 一年的哪一天 ( 001 到 366 ) |
%m | 一年的哪一個月 ( 01 到 12 ) |
%M | 分鐘 ( 00 到 59 ) |
%L | 毫秒 ( 000 到 999 ) |
%p | AM 或 PM. |
%S | 第幾秒 ( 00 到 61 ) |
%x | 日期組合 ( 月份縮寫 + 日期 + 年 ) |
%X | 時間組合 ( 小時 + 分 + 秒 ) |
%y | 西元年後兩位數的年份 ( 00 到 99 ) |
%Y | 西元年 |
知道這些參數之後就可以套用到 d3.timeParse()
中啦!
const date = '2019-09-23'
const parseTime = d3.timeParse('%Y-%m-%d')
const newDate = parseTime(date)
console.log(newDate) // Mon Sep 23 2019 00:00:00 GMT+0800 (台北標準時間)
溫馨小提醒:在使用 D3 進行時間轉換的時候要記得參數格式必須要跟傳進來的資料格式一樣,舉例來說今天有個日期是
'09-23'
這時候參數就必須要設定成'%m-%d'
,如果格式不一樣的話最後得到的結果就會是NULL
喔!
介紹了 d3.parseTime()
後,雖然時間是順利轉換了 D3 也可以順利的讀懂了,但是有個問題是這個轉換過的格式我們工程師看不懂啊!!! 所以接下來筆者要來介紹 d3.timeFormat()
這樣就可以順利地轉換成我們看得懂的格式了,不過使用 d3.timeFormat()
的時機是在 Axis
上,這個筆者會在之後的文章提到,這裡讀者對 Axis
稍微有個印象就好。
d3.timeFormat()
的寫法就跟 d3.parseTime()
一樣,差別在於 d3.timFormat
是自己可以設定之後日期的顯示格式,所以就不用按照原始資料的日期格式來進行參數的配置,這邊想怎麼寫就怎麼寫,寫法如下:
const date = '2019-09-23'
const parseTime = d3.timeParse('%Y-%m-%d')
const newDate = parseTime(date)
console.log(newDate) // Mon Sep 23 2019 00:00:00 GMT+0800 (台北標準時間)
const timeFormat = d3.timeFormat('%Y/%m/%d')
const normalDate = timeFormat(newDate)
console.log(normalDate) // 2019/09/23
最後就來做個簡單的組合並且把處理過後的資料丟到 domain 吧!還記得前天的文章提到 scale 中有一個 d3.scaleLinear()
嗎?通常用到 d3.timeParse()
的都會使用連續比例尺,藉由 d3.timeParse()
我們就可以把普通的時間字串轉為 D3 可以進行計算用的時間單位,如此一來便可以利用 d3.scaleLinear()
的特性讓 domain 只需要填入範圍值即可,接下來就用個簡單的範例碼來組合這幾天所講的內容吧!
// 設定 x 座標的比例尺
const width = 300
const x = d3.scaleLinear().range([0, width])
// 進行時間轉換讓 D3 在繪製的時候不會出錯
const originData = ['2019-09-23', '2019-09-24', '2019-09-25']
const parseTime = d3.timeParse('%Y-%m-%d')
const newData = originData.map(data => parseTime(data))
// 將轉換過的時間丟進 domain 中
x.domain(d3.extent(newData))
今天介紹了 d3.timeParse()
這個 API ,基本上要在 D3 的圖表中繪製跟時間有關的圖表都必須要利用 d3.timeParse()
先進行時間的轉換,直接單純的餵給 D3 時間字串是沒有用的喔!所以這也是為什麼筆者要多花一篇文章的篇幅來好好介紹一下 D3 的時間轉換。
如果對於文章有任何問題歡迎在下方留言給我,沒問題的話明天要來介紹 D3 另一個處理數值的 API 了。