在上篇我們講解了如何使用jQuery製作網頁上常用的動態長條圖,在本篇文章中我們將實際操作另外兩種框架:Vue/ D3的製作方法。還沒看上一篇的快快補唷👉 資料視覺化的動態長條圖製作(上):jQuery(直播筆記)
主要會用到的知識:
- HTML (Pug), CSS (Sass)與JavaScript/ jQuery的基礎觀念
- Vue框架概念
- D3框架概念
如果想搭配直播影片一起實作,請往這邊走👉 https://www.youtube.com/watch?v=o50XYczmoP0
框架二:Vue
Vue就像你雇用了一位負責代換抄寫的小幫手,你所需要做的就是提供資料的類型和處理方式,小幫手就會自動化地填入。
首先將剛剛jQuery完成的圖表直接fork,fork是幫你複製一個新的pen,修改時不會動到原本的東西。在JS的設定裡面代入Vue。
由於Vue的特性是在HTML寫模板,然後利用JS帶入資料,所以在HTML裡面新增.bar
,JS的部分先把height和background-color的設定複製起來,整個forEach的部分拿掉,//更新的地方暫時註解掉。
接著把Vue這個小幫手請出來幫我們抄寫跟產生DOM物件,告訴他工作的範圍後,也要指定原本的資料datas
,在HTML告訴他希望他幫我們重複打.bar
這個木樁10遍,同時把木樁的數值也打上去,用toFixed(1)
取到小數點第1位。
HTML
#app.graph .bar(v-for="data in datas") {{data.toFixed(1)}}
JavaScript
var datas = []; var elements = []; function generateData(){ var temp = []; for( var i=0; i<10; i++){ temp.push(Math.random()*10+5); } return temp; } for( var i=0; i<10; i++){ datas.push(Math.random()*10+5); } var vm = new Vue({ el: "#app", data:{ datas: datas } })
接著來設定長條方塊的樣式,透過Vue可以動態地去修改CSS屬性。在HTML新增:style="gen_style(data)"
,gen_style()像是一個方法,指導我們的小幫手說style要用data這個資料去算一個屬性(顏色、高度)做呈現。那小幫手要如何知道gen_style這個方法的實際內容呢?我們需在JS新增一個Method:{}
來告訴他。Method就像一本作業指導書,在裡面我們需要回傳一個JSON物件,用來說明CSS屬性的設定。因為rgb數值設定的關係,記得data需要先用語法parseInt()
處理成整數唷。
HTML
#app.graph .bar(v-for="data in datas", :style="gen_style(data)") {{data.toFixed(1)}}
JS
var vm = new Vue({ el: "#app", data:{ datas: datas }, methods:{ gen_style(data){ var d = parseInt(data); return { "height": data*20+"px", "background-color":"rgb("+data*10+","+data*10+","+data*10+")" }; } } })
登愣,神奇的事情發生了!我們明明沒有實際地對DOM物件做屬性指定的動作,他卻乖乖地自動產生對應資料的長條圖,這就是Vue好用的地方啦,就像你買了一台3D印表機,只要告訴他規則、資料,他就會自動幫你蓋好房子了。
剛剛我們用jQuery寫了一拖拉庫來達到每500毫秒自動更新的效果,在Vue只需要告訴他vm.datas = datas;
就可以完成囉。
//更新 setInterval(()=>{ datas = generateData(); vm.datas = datas; },500);
總地來說Vue的自動化很高、很方便,但相對他的產出就必須follow你訂下的規則,沒辦法一個一個做特定調整。
框架三:D3
D3有點像是jQuery的強化版,只是這次你拿的不是一支小破錘子,而是課金後的超炫砲無敵錘子,除了可以根據規則做重複的事情以外,還可以針對個體做客製化調整。
我們再fork一次剛剛jQuery完成的圖表。在JS的設定裡面代入D3。
剛剛在jQuery我們透過forEach把物件一個一個抓出來改,現在我們不需要單獨抓出來了所以先註解掉,取而代之的是批次抓取做修改,setInterval()的地方也暫時註解掉。
- 用
select()
選擇graph
裡面全部的bar
。 - 資料來源是
datas
請來這邊找。 - 因為現在bar還不存在而
datas
有10筆,透過enter()
來補齊物件跟資料差距的量。當DOM數量少於data的數量,或者壓根一個都沒有的時候,我們一般會使用enter()幫忙建立。 - append顧名思義就是添加的意思,透過
append()
新增div。 attr()
是負責命名這個div的class為bar。
d3.select(".graph").selectAll(".bar") .data(datas) .enter() .append("div") .attr("class", "bar")
有了十個bar之後接下來就是我們的重頭戲──調整高度和顏色。高度根據資料datas(d)中的第幾筆資料(i)去做調整,乘上20讓他差距更大、可視性更好,記得加上px因為他是CSS的屬性。
.style("height",(d,i)=>(d*20+"px"))
這邊要介紹D3中的一個概念:定義比例scale.linear()
。我們可以把它理解成地圖上常見的比例尺,例如台灣面積大約3萬多平方公里,要塞進一張 A4 大小的地圖根本是不可能的任務,這時候就必須要用到比例了。首先,命名一個函數為yscale
做線性轉換,domain()
代表「原始的資料範圍」,range()
則代表「轉換後的資料範圍」。先前我們在CSS把grpah的height設定為400px,所以設定轉換後range為0-400。
var yscale= d3.scaleLinear().domain([5,15]).range([0,400])
由console的結果可見yscale現在是一個可做等比例放大的函數,就像多拉O夢的放大燈ㄧ樣,藉由yscale我們也不需要再自己手動幫d乘上20增加他的級距了。
顏色也是用相同的概念處理,除了數值的放大轉換外,D3也可以幫你把數值轉成顏色。命名一個函數為color
,設定轉換成白色到紅色的區間。由console的結果可見color會自動幫我們把5-15的數值轉成rgb的色碼。
var color = d3.scaleLinear().domain([5,15]).range(['white','red'])
接著就來完成我們的圖表啦,使用語法style()做高度和顏色的設定,美美的圖表就大功告成了。
d3.select(".graph").selectAll(".bar") .data(datas) .enter() .append("div") .attr("class", "bar") .style("height",(d,i)=>(yscale(d)+"px")) .style("background-color", (d)=>color(d))
體會到D3的強大了嗎?雖然Vue的效能最好,但D3的優點在於他可以批次地處理一些華麗的動畫效果,例如上面的圖表還可以添加以下幾種語法,至於圖表會如何地變動就讓大家體驗看看囉!
.style("margin-bottom", (d)=>(200 - yscale(d)/2 + "px")) .transition().duration(500) .style("margin-bottom","0px")
最後再來個結尾小bonus,或許你也會有一樣的疑問。
讀者:「如果我想要有Vue的效率配上D3的華麗,到底該用哪一個呢?」
老闆:『爭什麼,摻在一起做成撒尿牛丸啊!』
Vue跟D3該如何結合呢?把剛剛用Vue完成的圖表叫回來,可以看到我們在height和background-color那做了一拖拉庫的處理,現在這些都可以交給D3來代勞。把剛剛在D3圖表用scaleLinear處理的程式碼貼過來,data的部分用yscale和color這兩個函數做計算,這樣就大功告成囉。
return { "height": yscale(data)+"px", "background-color": color(data) };
想看更複雜的結合使用,請往這邊走👉 codepen實作範例:長條圖_Vue&D3
框架比較
以上就是這次如何用三種框架實作長條圖的講解,希望這個介紹會讓大家對於各框架的優劣勢更加了解,在未來的專案中可以無痛使用,讓長條圖替你的網頁畫龍點睛吧!我們下次再見囉~
課程推薦
老闆在Hahow好學校開了兩門課,其中,動畫互動網頁程式入門(HTML/CSS/JS)以簡單例子帶你入門網站的基礎架構及開發,用素材刻出簡單有趣又美觀的網頁和動畫,享受做出獨一無二的網頁所帶來的成就感,在職場上與設計師和工程師合作無間。
打好基本的互動網頁基礎之後,可以進階動畫互動網頁特效入門(JS/CANVAS),紮實掌握JavaScript 程式與動畫基礎以及進階互動,整合應用掌控資料與顯示的Vue.js前端框架,完成具有設計感的互動網站。期待在課程裡見到你!