最近一直在研究數據可視化的相關理論和實現方案,相關實現技術和工具也了解使用了不少,需要寫篇綜述性的文章做整理。由於本人之前主要是做web開發的,故而我所找到的數據可視化的實現技術和工具大部分都是基於web的。這很正常,因為web便於分享和查看,如無意外我們都希望用瀏覽器直接訪問可視化作品。這篇文章主要記錄我使用心得。
1. HTML5 canvas
喬教主去世的前后兩年,HTML5非常火,在喬教主的指引下,HTML5仿佛是未來的明燈,將一統移動端和桌面的瀏覽器,甚至制造各種原生應用,似乎開個web相關會議不談談HTML5大方向就落伍了。但是到了2013年,HTML5的話題一下子沉寂了下來,仿佛之前的熱鬧都是假象——事實上這是因為這個東西已經從未來變成的現實,一個新技術進入了平穩發展期,自然沒必要像宣傳普及期那么大張旗鼓了。
HTML5標准主要是給給瀏覽器廠商看的,就是要讓瀏覽器支持從調用攝像頭到3d繪圖等一系列功能,通過統一標准來減輕web開發者的負擔。不過HTML5推進過程也不像原來想象得那么順利。HTML5遇到的最大問題是瀏覽器兼容性,標准不斷地補充修改,但是並非所有瀏覽器都能使用。造成這種現狀的原因有二,一方面有瀏覽器廠商因為利益原因大打出手(例如google反對h.264導致video標簽難產),一方面有個別瀏覽器廠商不求上進半天不支持主要標准(微軟現在也着急了,IE12已經迎頭趕上了)。
從2010年末起我就開始接觸使用HTML5相關的新技術。而用的最多的就是繪圖相關的canvas標簽。canvas標簽的瀏覽器兼容性比較好。根據最新的統計(百度統計|流量研究院 )。國內還在使用IE6的用戶已經接近10%。
<canvas></canvas>是html5出現的新標簽,像所有的dom對象一樣它有自己本身的屬性、方法和事件。 使用canvas的基本方式是,使用js調用canvas的API繪圖。例如,繪制一段貝塞爾曲線,需要用寫這樣一段javascript來生成:
function draw24(id) { var canvas = document.getElementById(id); if (canvas == null) { return false; } var context = canvas.getContext("2d"); //獲取convas 2d對象,其中封裝了很多繪圖方法(現在canvas只有2D對象可以調用) context.moveTo(50, 50); //移動繪圖中心點 context.bezierCurveTo(50, 50,150, 50, 150, 150); //繪制貝塞爾曲線 context.stroke(); //繪制邊框 context.quadraticCurveTo(150, 250, 250, 250); //繪制2次樣條曲線 context.stroke(); //繪制邊框 }
最后繪制的結果如下圖所示:
-
- 繪制曲線,這個例子摘自 《玩轉html5 canvas畫圖》
但是實際使用的時候我們通常不需要這樣直接調用API。如同原生的javascript API很繁瑣,調用起來比較麻煩,於是有很多JS庫(如jquery等)將其封裝以方便使用,HTML5 canvas也有相應的JS庫。我用過並感覺不錯的有如下一些:
- flot, 我第一個使用的canvas庫。基於jquery,支持有限的視覺形式(折線、條形、面積、點)和縮放等動畫效果,簡單易用。
- RGraph,我第二個使用的canvas庫。有優秀的動畫效果,特點是有大量的傳統統計圖的例子,並且很容易對這些例子做定制。
- chartJS, 該庫將很多基本統計圖的實現方法封裝起來,只要通過簡單調用即可以實現。這貨的優點就是簡單易用,不過如果要做深度定制恐怕還不太夠用。
- kineticJS, 是近來來canvas類庫中的新秀。這個庫的優點是在處理大量對象的時候很快,因為使用了多canvas技術。在它的官網上甚至能找到很多類似與flash動畫的例子。另外它的教程不錯。考慮到其他庫很多時候依賴例子定制,而這個文檔寫的好對於自主設計更有效,可能是目前最強的庫。
- porcessingJS, 它是著名的Processing語言的一個接口,用processing的語法以canvas進行繪圖,之后講processing的時候還會講到。優點是自由度大,缺點是沒有預定義模版,你可能需要到處找一些例子來學習。
- Echart, 一個由百度前端發起的canvas國產類庫。這個echart其實是在canvas類庫zrender的基礎上做的主題圖庫,優點有數據驅動,圖例豐富,功能強大,支持數據拖拽重計算,數據區域漫游,全中文文檔非常過癮。跟同樣是國產的前端腳手架fis一樣(官網http://fis.baidu.com/),都是誠意滿滿的國產套餐,體現了現今國內不俗的前端開發實力。我試用后感覺非常好,在我參與的一些項目中直接采用。關於我使用經驗參見:百度數據可視化圖表套件echart實戰
此外,我使用過但是感覺很糟糕的有:
dataV.js, 此乃浙大CAD&CG國家重點實驗室可視化與可視分析小組和阿里集團數據產品部門合作開發的開源可視化組件庫。我2012年初就關注並試用了。當時我興致勃勃地從github上下載了源碼,企圖用在自己的項目中。誰知第一個測試demo就各種出錯,我查了半天,竟然發現原始demo里就有錯誤,bug出在類庫的源碼里,而且不止一個官方demo有錯誤。這個類庫口號響亮令人震驚,但更新速度之緩慢令人震驚,文檔不全也令人震驚。為此我不得不替換成RGraph.js。現在已經過了兩年了,我回到他們的官網http://datavlab.org/,發現兩年來官網就沒怎么更新過!唯一的區別恐怕是原來官網上的幾個例子的鏈接還失效了(想當初我可是把他們的例子、文章全部點擊查看過)......從實用性上講,跟現在百度新推出的Echart類庫相比,2年前的datav.js弱爆了。而且官網長期不更新也讓我很難對現在的它抱有信任。
這里有一篇翻譯文章《知名html5 canvas庫對比》,比較了github上更多的此種類庫。有需要的朋友可以再到里面去看看。
最后再說說canvas這個技術本身的優缺點:
缺點:
- 只能繪制2D圖像,暫時不支持3D圖像。
- canvas繪制圖形出並非可以直接操作的dom對象。如果要對其進行類似dom的操作,例如添加屬性等等,比較麻煩(這就是為什么必須使用類庫)。
優點:
- 由於canvas繪圖不會給每個點生成對象,所以繪制速度快,消耗內存少。(這點主要是相對於SVG,VML技術而言)
- 兼容性較好。除了IE6,其他瀏覽器都可以支持。(IE7,8需要載入擴展JS,終究還是能用的)
2. SVG
關於SVG技術,在w3c的定義如下:
- SVG 指可伸縮矢量圖形 (Scalable Vector Graphics)
- SVG 用來定義用於網絡的基於矢量的圖形
- SVG 使用 XML 格式定義圖形
- SVG 圖像在放大或改變尺寸的情況下其圖形質量不會有所損失
- SVG 是萬維網聯盟的標准
- SVG 與諸如 DOM 和 XSL 之類的 W3C 標准是一個整體
由於矢量圖形技術的優越性(圖像在放大或改變尺寸的情況下其圖形質量不會有所損失,便於操作和編輯),因而將其應用於網絡成了板上釘釘的事情。SVG標准很早就出現了,2003年初就成為了W3C標准。但是,它的普及花費了很長時間,其中主要原因就在於微軟。由於2000年依賴微軟取得了在瀏覽器市場的壟斷地位,為了保持這種優勢,微軟有意地在IE系列中維持着一大批微軟標准,而無視w3c。當然對於當時的微軟來說它有這個底氣。本着壟斷的天性,微軟於微軟1999年9月附帶IE5.0一起發布了VML矢量圖形標記標准,有些人認為VML就是IE里的畫筆。VML其實是Word和HTML結合的產物,也是用XML詞表來定義。但是VML本質是word里圖形程序在IE上的遷移,不僅不開源,而且操作復雜,效率低。令人遺憾的是在IE長達10年的壟斷中一直只支持VM。IE6,7,8都不支持SVG,直到IE9才支持SVG。而現在,喪失瀏覽器壟斷地位的微軟終於認清現實,VML是已經過時的技術,在IE10中不予支持。詳見微軟的申明。
SVG最大的優點就是繪制和控制簡單。直接在html頁面里加入xml語句就可以編輯繪制。例如下面的代碼就是畫一個圓、一個橢圓和一道黑線,把這段代碼另存為一個html文檔再用谷歌瀏覽器打開就能看到效果了:
<html> <svg> <circle cx="25" cy="25" r="22" fill="blue" stroke="gray" stroke-width="2" /> <ellipse cx="250" cy="250" rx="100" ry="200" fill="yellow"/> <line x1="0" y1="0" x2="500" y2="50" stroke="black"/> </svg> </html>
跟前文中canvas繪圖的方式比一比,就知道SVG是多么容易控制了。
當然,使用SVG時我們通常也是使用類庫來提升效率。這里的類庫主要有三種:
- highcharts.JS, 在現代瀏覽器中使用SVG繪圖,在IE6,7,8中用VML繪圖。包含一堆預定義的圖表和樣式。唯一的問題是,這貨收費。只對非商業用途免費。
- raphael.js,以著名畫家拉斐爾之名命名的繪圖JS庫,跟highcharts類似,也是SVG + VML兼容性方案。 但它是開源的,應用也比較廣泛。使用它的時候有必要再下一個gRaphael圖表庫作為參考。
- D3.js,D3js是應用在web開發上的開源JS組件庫,是一個數據可視化工具。D3應用的最為廣泛,不過只支持SVG,我會重點講述。
D3的全稱是Data-Driven Documents(數據驅動文檔),在github上關注數量超過了2萬人(超過了所有canvas類庫的關注數量),是非常受歡迎的開源工具。使用d3的有開發者,有設計師,有藝術家,資料非常豐富(雖然中文的很少)。關於D3的我的應用案例可以見我之前的文章《D3js初探及數據可視化案例設計實戰》。
那么接着說說D3的優缺點(基本上也就是SVG的優缺點):
優點:
- D3最大的優點在於其資料豐富,案例非常多。這是真的是一個極大的優點。
- SVG矢量圖形的特點是無損縮放,這個優勢在顯示2D圖形式會有非常好的效果,並且兼容各種分辨率。
- SVG圖形的節點可以像dom元素一樣控制,這就讓自主創作圖形變得更容易。相對於canvas這也是非常大的優勢。
缺點;
- SVG是2D矢量圖,不能畫3D圖形。(用2D矢量可以畫很多帶透視效果的偽3D圖,那並不是真正的3D圖!)
- d3.不支持IE6,7,8。如果想要IE8使用d3,請用r2d3.js(一個結合了 Raphael.js的擴展庫)。Raphael.js是一個跨瀏覽器的矢量圖形庫,它實現IE6,7,8兼容的方法是:在IE6,7,8中使用VML,在其他瀏覽器中使用SVG。另外,如果圖形復雜,就不要指望用Raphael.js在IE上能跟D3畫出一樣酷炫的效果。
- SVG的節點都是對象,非常占用內存。例如論壇里一個朋友使用d3繪制超過12000個節點的圖,直接導致每個試圖打開它的瀏覽器都崩潰了。這個時候如果不願意做簡化那么應該試試canvas繪圖。
最后,補充一個問題,如何在IE6這樣的古董瀏覽器上繪制可交互的統計圖形?
經過我長期摸索實踐,結論是,不要試圖這樣做。即便是VML兼容方案性能也很差。在IE6上最靠譜的做法是用php或者java直接在后台繪制一個jpg圖片,然后發到IE6上顯示。這個方法也是5,6年前最通用的做法,現在已經過時了。最好的策略是,不要對IE6兼容,實在不行的話就顯示一個不能動的圖片吧!珍惜時間,珍惜生命,遠離IE6!
3. webGL
前面說的繪圖技術,無論canvas還是SVG都不能繪制3D圖形。我曾經見過很多在網頁上顯示3d圖形的方案,但都需要你的電腦上安裝相應的插件(例如flash, silverlight)或者事先安裝虛擬機(例如java)。之前曾經有過很多web 3D渲染技術,但不是要下插件,就是編程復雜,於是漸漸被時代淘汰,例如VRML,約翰•卡馬克已經宣布了它的死亡。難道就沒有一個開源的通用標准顯示3D圖形嗎?
當然是有的。這貨叫webGL, 是一項使用JavaScript實現3D繪圖的技術,瀏覽器無需插件支持,Web開發者直接使用js調用相關API就能借助系統顯卡(GPU)進行編寫代碼從而呈現3D場景和對象。
WebGL標准由科納斯組織(Khronos Group)開發和維護,Google、Mozilla、Opera和Apple 等瀏覽器廠商都是其中的成員,為這一標准做出了顯著貢獻。從名稱上我們就可以知道WebGL跟openGL肯定是小弟與大哥的關系。事實上webGL是基於OpenGL ES 2.0開發的,OpenGL ES 是 OpenGL 三維圖形 API 的子集,針對手機、平板電腦和游戲主機等嵌入式設備而設計。瀏覽器內核通過對OpenGL API的封裝,實現了通過JavaScript調用3D的能力。WebGL 內容作為 HTML5 中的Canvas標簽的特殊上下文實現在瀏覽器中(這下canvas終於可以畫3D圖了,雖然用的是不同技術)。
-
- webGL誕生時期放出的經典例子:深海水族館
webGL技術從初創到現在也不過2年多的時間(2011年發布標准),但是發展很快。一開始傲嬌的微軟認為該技術有極大的安全漏洞而拒絕使用(因為相當於讓web腳本直接控制了顯卡這么重要的硬件,同時有沒有類似windows update這樣的更新程序來彌補漏洞),但是現在也放下身段在IE12里面支持了此物。原因無他,就是HTML5帶來的潮流:在功能上,web應用將會越來越像內建應用。它可以調用顯卡,調用麥克風,調用攝像頭,調用一切能用的硬件去提升服務質量。這一切都基於瀏覽器的支持。
webGL的各大瀏覽器支持情況(截至2013年11月):
桌面瀏覽器
- Mozilla Firefox 4+
- Google Chrome 8+
- Internet Explorer 11+
- Safari 5.1+
- Opera 12+
移動瀏覽器
- Firefox 25+
- Google Chrome 31+
- Opera Mobile 12+
- Android Browser 暫不支持
- iOS Safari暫不支持
- IE Mobile 暫不支持
從上面的支持情況列表我們可以發現,支持情況還是比較可喜的,至少現代瀏覽器都支持,移動端和IE略有落后。不過畢竟這個技術還是新鮮事物,在國內能找到的資料還很少,國內前端技術圈討論也不多,是真正的技術藍海。本人並沒有實際開發過webGL程序,目前還停留在觀察階段。若有工作需求,會將其列入研究重點。
讓我們查看一些webGL的案例,當然是mozilla demostudio的最好。
最后,讓我們提一提webGL的JS框架,它們可以減少工作量並提供一些有趣的例子。
- philoGL,專注於3D可視化的一個webGL框架。
- threee.js, 谷歌團隊Data Arts出品的基於webGL的3D場景庫,它的演示十分有趣。
4.flash & actionscript
flash這個東西我是又愛又恨。愛是說我從初衷起就接觸過這個東西,很喜歡它做的flash動畫,並在大一大二也學過一陣;恨的是flash與web頁面其實是完全分離的玩意,不僅要用自己的一套actionscript編寫(並且as不如JS好使,我個人感覺),加載也要下載插件。在HMTL5+JS+CSS3的時代,越發覺得flash的大多數功能已被替代。
猶記當年喬教主2010年就怒噴過flash,認為它是移動端的阻礙,不適合觸摸設備,技術封閉,已經過時。並且宣布蘋果公司的產品在日后不支持flash。此舉立即得到了微軟、谷歌的響應。尤其是在經過HTML5的一番宣傳以后,2010年前后大家都看淡flash的前景而看好HTML5。但是作為flash的老東家Adobe公司的發言人卻一再表示:flash已經應用的非常普遍,想把我們一腳踹開是不可能的。現在究竟是鹿死誰手呢?經過3年的折騰,我們看到flash還是好端端地活着,當然份額確實減少了些。蘋果還是立場堅定地拒絕flash支持html5,但是html5發展並不順利;谷歌一面支持html5,一面也支持flash(你看現在的android手機不支持個flash都不好意思出門),同時還在折騰自己的視頻標准害的HMTL5的視頻標准一再難產;微軟則在旁觀,同時養活着flash,html5和自家的silverlight。可以說HMTL5聯盟曾經試圖聯手杯葛flash, 結果由於各家心懷鬼胎而失利。HTML5的最終效果也沒有完全達到flash的水准,雖然在很多領域(例如樣式、繪圖等等)已經基本上差不多了,但是至少在動畫編輯這一塊,HTML5至今也沒有一個像adobe flash cs5 這么強大易用的編輯工具。
當初flash之所以能實現很多web頁面不能實現的功能,是因為web標准從一開始就被設計地注重安全性,不能操作本地資源(典型的例子,到現在JS都不能操作內存);而flash是個本地程序,可以自由地調動本地資源,所以可以實現很多需要耗費大量本地資源的效果,例如2D動畫、3D動畫。但是隨着計算機功能越發完善,很多2000年初很耗費資源的功能,現在看起來不值一提。HTML5則是從瀏覽器標准一級,要求瀏覽器能調用這些本地資源。這就是之前所說的HTML5帶來的潮流:在功能上,web應用將會越來越像內建應用。所以未來flash終將被淘汰。但是adobe不會因此餓死,因為Adobe也不是用flash來賺錢,而是用flash編輯器來賺錢,如今也在flash編輯器中加入了html5元素,保證就算flash完蛋也能繼續掙錢。
那么談談用flash構建可視化應用吧。由於flash在繪圖、動畫效果上長期保持的優勢,所以過去有很多人用flash創建可交互的額數據可視化圖表。並且如同那些js canvas類庫一樣,flash也有這樣的類庫。
5.java & processing
processing是久負盛名的為了實現交互式可視化創作的Java語言擴展,我在《Benjamin Fry的《可視化數據》和processing語言》一文中有過介紹。不過我並沒有直接用過processing,而只用過processingJS, 一個使用processing語法的使用html5 canvas繪圖的JS類庫。在前文中已經有過推介。
6. R
R語言之前我已經多次提到了。這段時間我也開始試用,不過說句實話這個東西我覺得不能稱為語言,我感覺它不像C++,更像mathlab這樣的應用程序。它的圖標很簡陋,GUI更簡陋,簡直除了控制台再沒有別的了。我想這是制作它的統計學家的心聲:科學不是花里胡哨的玩意,它其實很枯燥,但很注重內在美!
-
- 我用R軟件繪制了一個最簡單的圖。剛安裝完R所做的測試。
SPSS和SAS是數據分析行業的標准工具,也能生成各種統計圖形。不過這兩個軟件授權費那是相當昂貴。SAS我在高校實驗室蹭過,但是目前手頭上能用的只有R和盜版mathlab。R語言的操作跟mathlab很像,基本上都是自己寫一段程序讓它去運行。這里要談談R語言跟mathlab的區別。
- mathlab是商業軟件,R是開源軟件;mathlab我們幾乎都在用盜版,R我們想用就用;由於是商業軟件,別的程序很難調用mathlab程序;而R就是希望別人調用它,並且它自己也可以引用其他高於語言C, java ,python, ruby等寫的代碼。
- mathlab是數學家發明的,而R是數學家中的統計學家發明的;
- 有人說mathlab在某些算法上比R快,不過我還沒感覺到;
- mathlab的3D圖像要比R豐富;R畫畫2D圖還行,畫3D圖又丑又慢。當然,R一直在改進。