当前位置: 首页 > 資訊 >

#25-讓長條圖一條條動起來~大數據時代!入手 D3.js~

自己做行銷的時候,很喜歡玩數據
數據可以打破一些先入為主的想法、
也可以給我們更全面的視角、或是新的發現。
也因此產生了學習D3的念頭。

近幾年來流行大數據、 Infographic,
網頁也是有機會需要呈現這些數據表格,
有了動態資訊的呈現,就不會這麼枯燥乏味!

最近看到的是這一篇講軟體工程師的技術、就業等趨勢報告,
除了他們本身網站配色就很亮眼外,配合上好的動態效果,讓無聊的數據有趣了起來:

南非軟體工程師報告(英文)

D3.js 是擅長資料處理的一個Javascript資料庫,
從推出以來已經十年了,作法跟jQuery 很像,可以直接選取物件,
再餵食Data給他,就會長出圖表來。(當然還是有很多設定啦!)

老樣子,我不會講基礎原理,
而是要硬逼自己生出一個動態來,
不過也會在code裡面說明一下原理和方法。(做中學最好玩了!)

還是老樣子,(什麼時候有新樣子?)先來看一下今天的成果~

抓了南非的年齡分佈失業比率,
非洲下一個問題是如何創造就業機會給龐大的年輕人口
下面先推薦一下學習工具,想看code請跳過~


推薦D3學習工具

!!!大推!!!
三十天成為D3.js v7 好手

金金的2021鐵人D3文章,絕對是D3入手必備!
除了深入淺出介紹D3外,金金的文筆很好、文章邏輯的架構很清楚,很適合閱讀,
加上有搭配很多精美的解說圖片和GIF檔案,把複雜的高牆都一一擊破了。
(她的一篇文章知識含量是我的2-3篇...)

d3官方網站
https://d3js.org/
https://observablehq.com/@d3/gallery

推薦oxxostudio的D3系列文章(中文)~共有20多篇文章,幾乎就是一個鐵人賽了XD
https://www.oxxostudio.tw/articles/201410/svg-d3-info.html

D3教學網站(英文):
https://www.tutorialsteacher.com/d3js

https://www.d3-graph-gallery.com/index.html


動態長條圖

靜態繪圖

靜態畫圖的部分,上code解釋:

//html 其實就是一個div啦
<div class="graph1"></div>

//JS部分 
//要記得cdn d3唷:
<script src="https://d3js.org/d3.v7.min.js"></script>

//data陣列,D3也可以直接吃csv檔案d3.csv()
const unemploymentData = [
  {
    item: '15-24 y',
    value:0.63
  }, ...以下省略]

//接著開始畫圖形囉!主要就是4大步驟:
//1.基本設定
  const svg = d3.select('.graph1') //選取div
				.append('svg') 
				.attr('width',200)
				.attr('height',200)//div裡面加上一個長寬200的svg

//2.比例尺設定,下面會變成一個function,幫你計算每一個矩形x,y對應位置
//這邊有滿好的解釋:https://segmentfault.com/a/1190000011006780
	let xScale = d3.scaleBand() //我的scale要一條一條對應
	               .domain(d3.range(unemploymentData.length))//看要幾條
	               .range([0,200])//要畫在svg哪裡
	               .padding(0.1)
                   
  let yScale = d3.scaleLinear()
				.domain([0, 1])//data的範圍,我的資料都是0.多,最多就是1囉
				.range([200,0])//range要反過來,不然會倒過來長

//3.畫長條圖啦
	//先把所有的矩形選取來,d3可以在rect被畫上之前就選取,網路上搜尋會有一些解釋~
  const rect = svg.selectAll('rect')
    rect.data(unemploymentData) //把資料要塞到矩形裡面
    .enter() //給每一個資料一個元素對應
	.append('rect')//對應元素我要矩形
    .attr('width',24)//矩形寬度
    .attr('fill','orange')//矩形顏色
    .attr('x', (d, i)=>{return xScale(i)})//算x位置
    .attr('width',xScale.bandwidth())//內建函數算x肥度
    .attr('y', (d)=>{return yScale(d.value);})//算y位置
    .attr('height',(d)=>{return yScale(0) - yScale(d.value)}) //算y要長多高,是反過來的,因為0在上方

//4.上標籤文字!
  svg.selectAll('text').data(unemploymentData)
    .enter()
    .append('text')
    .text((d)=> {return d.item})
    .style("text-anchor", "end")
    .attr("transform",function(d,i){ return "translate(" + (15+xScale(i)) + ", 210) " + "rotate(-90)"}) //文字太長了我要旋轉他!
	.style("font-size", 16)
    .style("fill", "#ffffff")

加上動態

其實D3 很簡單,
跟CSS一樣名稱,只要加上transition()
他就會幫忙顯示前後code的變化。
譬如說我就在長度100前面放一個長度0,
中間穿插一個transition就會幫我們顯示了!

然後bar就是要一條一條出現才好看啊!
可以直接用D3內建的 .delay功能(英文就是延遲呀)
讓他們一個一個延遲N秒:.delay(function(d, i) { return i * n; })

下面就把transition&delay補在下面:


    rect.data(unemploymentData)
    .enter() 
	.append('rect')
    .attr('width',24)
    .attr('fill','orange')
    .attr('x', (d, i)=>{return xScale(i)})
    .attr('width',xScale.bandwidth())
    .attr('y', yScale(0)) //先在y最遠的地方就定位
    .transition() //動態插入開始!
    .duration(1000)
    .delay(function(d, i) { return i * 100; }) //動態插入結束!下面就是告訴他我要長高呀
    .attr('y', (d)=>{return yScale(d.value);})
    .attr('height',(d)=>{return yScale(0) - yScale(d.value)})

//標籤文字也是如法炮製~

今天的成果放這邊


以上!

我沒有很好地加上X & Y軸,
有興趣的可以參考金金的這一篇:Day22-D3 基礎圖表:長條圖

有任何錯誤&想法再請多指教!!