iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 20
0
Modern Web

資料視覺化!D3入門到實戰系列 第 20

Day20 實戰!Github Heat Map 產生器_Heat Map實作(1)

  • 分享至 

  • xImage
  •  

什麼是熱力圖(Heat Map)?

熱力圖常用來描述數據的分佈,使用上有兩種狀況:第一種搭配地圖或照片,讓人可以看出來某個資料在地域上的分佈,例如某項傳染病例在某地區的分佈,或是底圖是網頁,看出點擊分佈來分析使用者行為:

圖片來源:https://kknews.cc/tech/gvrbyn9.html

圖片來源:https://kknews.cc/tech/gvrbyn9.html

另外一種則是我們準備要實作的,資料在二維或三維座標上的分佈,例如一週內捷運進站人數的時間分佈,或是不同家店的客人時間分布差異。

圖片來源:http://qlikdork.com/2015/02/visualizing-busy-ness/

用D3繪製Heat Map

那到底要怎麼畫熱力圖呢?我們可以同長條圖或折線圖那樣想,熱力圖一樣擁有xy軸,而每個方塊的位子就像d3幫我們算的折線圖的點,只不過數值是我們自己定義的。但因為在這個專案的熱力圖,每一個格子是有固定寬高的,所以不用特別去算scale。

那首先我們先來建立假資料:

const data = [];
// 建立隨機365天的資料
for (let i = moment('2019-01-01'); i.isBefore('2020-01-01'); i.add(1, 'days')) {
    data.push({
      value: getRandomInt(0, 100), //1-100隨機數字
      weekNum: i.weekYear() === 2019 ? i.week() : i.week() + moment('2019-01-01').weeksInYear(), //一年的第幾個禮拜,因為一年的最後兩三天會被計算成下一年的第一週,所以要先判斷是不是當年的週次,如果不是的話就要加上當年的周次
      day: i.day(), //星期幾
      date: i.format('YYYY-MM-DD') //日期
    })
}

再來就是在div中加入svg:

const margin = {
    top: 15,
    bottom: 15,
    left: 15,
    right: 15
};

const chartWidth = 900 - margin.left - margin.right;
const chartHeight = 160 - margin.top - margin.bottom;

const svg = d3
    .select(`#${id}`)
    .append('svg')
    .attr('width', chartWidth + margin.left + margin.right)
    .attr('height', chartHeight + margin.top + margin.bottom);

下一步就直接把正方形們畫上去,今天的目標是不要管資料的顏色,只要把位子調好就可以了

const g = svg
    .append('g')
    .attr('transform', `translate(${margin.left}, ${margin.top})`);

g.selectAll('.block')
    .data(data)
    .enter()
    .append('rect')
    .attr('class', 'block')
    // x為week值 * 正方形的寬 + week值 * 正方形之間的間距,因為第一個week值是一,所以若要讓方形靠最左邊就要-1
    .attr('x', d => (d.weekNum - 1) * 15 + (d.weekNum - 1) * 1)
    // y為星期的值 * 正方形的高 + 星期的值 * 正方形之間的間距
    .attr('y', d => d.day * 15 + d.day * 1 + 10)
    .attr('fill', 'black')
    .attr('width', 15)
    .attr('height', 15)
    .attr('rx', 3);

如此一來就能得到熱力圖的正方形們了,資料長度為一年。
https://ithelp.ithome.com.tw/upload/images/20190919/20119937xKcJUD5d3M.png


附上今日的commit: https://github.com/yuanchen1103/2020ironman-github-contributions/commit/124bd04e808e680f37d5d9cc733581468887bcde


上一篇
Day19 實戰!Github Heat Map 產生器_在React中使用D3
下一篇
Day21 實戰!Github Heat Map 產生器_Heat Map實作(2)
系列文
資料視覺化!D3入門到實戰30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言