本篇大綱:Fetch 檔案的 API 們:d3.json( )、d3.csv( )、d3.tsv( )、d3.dsv( )
今天我們要來看到 D3 的另外一類 API 們:Fetches (d3-fetch)
前幾篇講到資料跟 DOM 元素如何綁定的時候,我們使用的資料都是自己設定,但實務上操作時,資料通常都是從後端提供的API、或是行銷、PM 那邊提供的 excel 檔案而來,而且這些資料的架構複雜度也絕對跟我們自訂的簡單陣列不一樣。所以接下來,我們就要介紹:
在開始講如何用 D3.js 取得不同檔案資料前,我們要先有檔案可以使用~所以,先來介紹幾個不錯的公開資料平台
這是我自己最喜歡、覺得很好用的公開資料平台。可以根據自己想找的資料搜尋,而且每項資料後面也都會標註提供什麼樣格式的檔案,使用上非常方便
各縣市政府資料開放平台:台北市資料大平台、新北市政府資料開放平臺
近幾年來開放資料的風氣蠻盛行的,所以各縣市大多也都有建立了開放資料的平台~有興趣的人可以自己挑選想使用的市政府資料平台去玩玩看哦~
內政資料開放平臺
老實說我覺得這個平台沒有很好用,資料的查找上也比較複雜,不過有興趣的還是可以用用看
中央氣象局-氣象資料開放平臺
這個也是我很喜歡的網站~小缺點是想拿資料要先註冊並登入,但畫面的設計跟查找功能很好用,而且也包含最齊全的氣象資料 (廢話
以上是我覺得不錯的網站,接下來我們來看看要怎麼取得資料吧!
D3.js 為了方便大家取得不同來源的資料,針對不同資料的格式提供了不同的AP,我們這邊就來看到最常用的幾種:
d3.json(url, init)
⇒ 透過 API 取得 json 檔案的資料一般來說,我們繪製圖表時,最常見使用的就是 API 回傳的json資料,這邊先以 政府資料開放平臺 內提供的 新竹縣政府水資源回收中心每日排放量 來示範
*注意:如果你的 json 資料檔直接存在自己的檔案內,不需要透過呼叫 api 的方式取得,那就直接使用 d3.json('相對路徑')就好,更方便也不會遇到 CORS 的問題。
首先,先找到「新竹縣政府水資源回收中心每日排放量」的JSON檔網址:
https://ws.hsinchu.gov.tw/001/Upload/1/opendata/8774/1380/af80d954-d968-42a0-bc97-a2f801840b65.json
接著,再使用 d3.json 來取得資料
async function getCorsData() {
dataGet = await d3.json("https://ws.hsinchu.gov.tw/001/Upload/1/opendata/8774/1380/af80d954-d968-42a0-bc97-a2f801840b65.json");
console.log('dataGet', dataGet);
}
getCorsData();
但是這時我們會看到 console 上出現了CORS 錯誤,這是瀏覽器設定的同源限制,禁止不同網域的伺服器存取資料。如果不太清楚什麼是CORS錯誤,建議去看看 胡立寫的CORS完全系列手冊
如果你是用node.js來開發,或是有用其他前端框架來寫D3.js,那我建議直接設定 proxy 來解決CORS問題;但因為我這邊使用最簡單的原生 JS 引入 d3.js CDN 來開發,而且也只需要 get 資料就好,因此我會借助 heroku-cors-anywhere 來解決CORS。
heroku-cors-anywhere 的方法很簡單,直接將heroku-cors-anywhere設定好的網址加到我們要取得資料的網址之前就行
// 跨網域存取 API 資料
// 使用 cors-anywhere
const cors = "https://cors-anywhere.herokuapp.com/";
const url = "https://ws.hsinchu.gov.tw/001/Upload/1/opendata/8774/1380/af80d954-d968-42a0-bc97-a2f801840b65.json";
async function getCorsData() {
dataGet = await d3.json(`${cors}${url}`); // 串接網址
console.log('dataGet', dataGet);
}
getCorsData();
有些人用 https://cors-anywhere.herokuapp.com/
這個網址時會遇到 403錯誤
這時也不用擔心,只要將網址改成 https://secret-ocean-49799.herokuapp.com/
就行了
// 跨網域存取 API 資料
// 使用 cors-anywhere
const cors = 'https://secret-ocean-49799.herokuapp.com/';
const url = "https://ws.hsinchu.gov.tw/001/Upload/1/opendata/8774/1380/af80d954-d968-42a0-bc97-a2f801840b65.json";
async function getCorsData() {
dataGet = await d3.json(`${cors}${url}`);
console.log('dataGet', dataGet);
}
getCorsData();
這樣就能順利取得資料啦~
d3.csv(url, init, funcion)
⇒ 取得 csv 檔案的資料 (dsv、tsv檔案也是一樣用法)另外一種很常見的資料格式是csv檔案,這邊我們用 政府資料開放平臺 內提供的COVID-19各國家地區累積病例數與死亡數 來示範
下載好資料開放平台提供的csv檔案之後,把它存到資料夾內,接著用 d3.csv( ) 這個方法取資料
// 拿取csv資料
const getCsvData = async ()=>{
const csvData = await d3.csv('./covid19_global_cases_and_deaths.csv')
console.log('csvData',csvData)
};
getCsvData()
這樣就能在 console 中看到取得的資料了
值得注意的是,d3.csv( url , init, function) 可以帶入三個參數,分別是「網址、順序、函式」, 因此我們可以一樣可以使用第三個 function 來設定一些條件。例如,我只想取得所有 country_ch 的值
// 拿取csv資料
const getCsvData = async () => {
const csvData = await d3.csv('./covid19_global_cases_and_deaths.csv', d=>{
return d.country_ch // 只取country_ch
})
console.log('csvData',csvData)
};
getCsvData()
取出來的資料就會變成:
以上就是怎麼用 d3 的 API 去取資料啦,是不是很簡單呢?d3.js 把困難的部分都幫我們做掉了,所以就能專注在之後的資料處理上囉!那今天的內容就到這邊,想到中秋連假明天不用上班就覺得開心,可以專心地來趕稿啦!
這邊附上本章的程式碼與圖表 Github 、 Github Page,需要的人請自行取用~這是的資料一樣是看console 回傳的內容唷,記得打開 devTool ~