用500行純前端程式碼在瀏覽器中構建一個Tableau

發表於2018-05-16

在Gartner最新的對商務智慧軟體的專業分析報告中,Tableau持續領跑。Microsoft因為PowerBI表現出色也處於領導者象限。而昔日的領導者像SAP,SAS,IBM,MicroStrategy等逐漸被拉開了差距。

用500行純前端程式碼在瀏覽器中構建一個Tableau

Tableau因為其靈活,出色的資料表現已經成為BI領域裡無可爭議的領頭羊。而其資料驅動的視覺化和核心思想是來自於Leland WilkinsonThe Grammar Of Graphics ,同樣受到該思想影響的還有R的圖形庫ggplot

用500行純前端程式碼在瀏覽器中構建一個Tableau

在資料視覺化開源領域裡,大家對百度開發的echarts可謂耳熟能詳,echarts經過多年的發展,其功能確實非常強大,可用出色來形容。但是螞蟻金服開源的基於The Grammar Of Graphics的語法驅動的視覺化庫G2,讓人眼前一亮。那我們就看看如何利用G2和500行左右的純前端程式碼來實現一個的類似Tableau的資料分析功能。

 

資料載入

第一步是載入資料:

用500行純前端程式碼在瀏覽器中構建一個Tableau

資料載入主要用到了三個庫:

資料通過我存放在GitHub中的csv格式的檔案,以REST請求的方式來載入。下面的程式碼把Axios的Promise變成 async/wait方式。

封裝好後,我們就可以用request.get()方法傳送REST請求,獲取csv檔案。

這一步可能會遇到跨域請求的問題,github上的檔案支援跨域。

把資料儲存在一個SQL資料庫中,這樣做的好處是為了下一步做資料準備的時候,可以方便的利用SQL來進行查詢和分析。

SqlTable是一個對資料表的封裝,把csv資料存在SQL資料庫表中,提供一個query()方法。這裡要做的是把SQL查詢個從 “SELECT * FROM table” 變成 “SELECT * FROM CSV(?)” 表示查詢引數是CSV資料。因為codepen的安全性限制,執行前向查詢的replace語句(這裡的regex表示把前面是“FROM ”詞的替換為CSV(?)的)在full page view下是不能執行的,所以我用了一個更簡單的假定,使用者的表名就是table,這樣做有很多問題,大家如果在codepen之外的環境,可以用註釋掉的程式碼。

然後把”SELECT * FROM table”的查詢結果(JSON Array)用datatable來展示。

這一步有兩點要注意:

  1. 資料中,如果列的名字中有包含點,空格等字元,例如Iris資料集中的Sepal.Length,datatable是無法正常顯示的,這裡要呼叫sanitizeData()方法把列名,也就是JsonArray中Json物件的屬性名中的點和空格去掉。
  2. sanitizeData()方法會改變輸入物件,所以在傳入之前做了一個深度拷貝,這裡利用JSON的stringfy和parse方法可以對JSON相容的物件有效的拷貝。

這裡要注意,Iris資料集中在datatable中的列名都不顯示點,但實際資料並沒有改變。

 

資料準備

資料載入完畢,我們來到第二步的資料準備階段。資料準備是資料科學專案最花時間的一步,通常需要對資料進行大量的清洗,變形,抽取等工作,使得資料變得可用。

在這一步我們做了兩件事:

一是顯示資料的一個摘要,讓我們初步瞭解資料的概貌,為進一步的資料變形和處理做好準備。

這個是Iris資料集的摘要:

用500行純前端程式碼在瀏覽器中構建一個Tableau

這裡我們利用資料的型別判斷出每一個欄位是數值型還是字元型。對於字元型的欄位,我們利用JS6的Set來獲得所有的Unique資料。對於數值型,我們利用d3的max,min,mean,median,deviation方法計算出對應的最大值,最小值,平均數,中位數和偏差。

另一個就是利用SQL查詢來對資料進行進一步的加工。

用500行純前端程式碼在瀏覽器中構建一個Tableau

上圖的例子中我們利用限制條件得到一個Iris資料的子集。

另外G2還提供了Dataset的功能:

  • 源資料的解析,將csv, dsv,geojson 轉成標準的JSON,檢視Connector
  • 加工資料,包括 filter,map,fold(補資料) 等操作,檢視 Transform
  • 統計函式,彙總統計、百分比、封箱 等統計函式,檢視 Transform
  • 特殊資料處理,包括 地理資料、矩形樹圖、桑基圖、文字雲 的資料處理,檢視 Transform

資料處理是一個比較大的話題,我們的目標是利用盡可能少的程式碼完成一個資料分析的工具,所以這一步僅僅是利用alasql提供的SQL查詢來處理資料。

 

資料展示

資料處理好後就是我們的核心內容,資料展示了。

用500行純前端程式碼在瀏覽器中構建一個Tableau

這一步主要是利用select2提供的選擇控制元件構建圖形語法來驅動資料展示。如上圖所示,對應的G2程式碼圖形語法為:

圖形語法主要包含以下幾個主要的元素:

 

幾何標記 Geometry

幾何標記定義了使用什麼樣的幾何圖形來表徵資料。G2現在支援如下這些幾何標記:

geom 型別 描述
point 點,用於繪製各種點圖。
path 路徑,無序的點連線而成的一條線,常用於路徑圖的繪製。
line 線,點按照 x 軸連線成一條線,構成線圖。
area 填充線圖跟座標系之間構成區域圖,也可以指定上下範圍。
interval 使用矩形或者弧形,用面積來表示大小關係的圖形,一般構成柱狀圖、餅圖等圖表。
polygon 多邊形,可以用於構建色塊圖、地圖等圖表型別。
edge 兩個點之間的連結,用於構建樹圖和關係圖中的邊、流程圖中的連線線。
schema 自定義圖形,用於構建箱型圖(或者稱箱須圖)、蠟燭圖(或者稱 K 線圖、股票圖)等圖表。
heatmap 用於熱力圖的繪製。

這裡要注意,intervalstack是官方支援的,但是文件沒有提到,在閱讀G2的API文件的時候,我也發現文件講的不是很清楚,有很多地方沒有講清楚如何使用API。這也是開源軟體值得改進的地方。

 

圖形屬性 Attributes

圖形屬性對應視覺編碼中的不同元素,大家可以參考我的另一部落格 資料視覺化中的視覺屬性 。

圖形屬性主要有以下幾種。

  1. position:位置,二維座標系內對映至 x 軸、y 軸;
  2. color:顏色,包含了色調、飽和度和亮度;
  3. size:大小,不同的幾何標記對大小的定義有差異;
  4. shape:形狀,幾何標記的形狀決定了某個具體圖表型別的表現形式,例如點圖,可以使用圓點、三角形、圖片表示;線圖可以有折線、曲線、點線等表現形式;
  5. opacity:透明度,圖形的透明度,這個屬性從某種意義上來說可以使用顏色代替,需要使用 ‘rgba’ 的形式,所以在 G2 中我們獨立出來。

在構建語法的時候,我們把圖形屬性繫結一個或者多個資料欄位。

 

座標系 Coordinates

座標系是將兩種位置標度結合在一起組成的 2 維定位系統,描述了資料是如何對映到圖形所在的平面。

G2提供了以下幾種座標系:

coordType 說明
rect 直角座標系,目前僅支援二維,由 x, y 兩個互相垂直的座標軸構成。
polar 極座標系,由角度和半徑 2 個維度構成。
theta 一種特殊的極座標系,半徑長度固定,僅僅將資料對映到角度,常用於餅圖的繪製。
helix 螺旋座標系,基於阿基米德螺旋線。

 

分面 Facet

分面,將一份資料按照某個維度分隔成若干子集,然後建立一個圖表的矩陣,將每一個資料子集繪製到圖形矩陣的窗格中。分面其實提供了兩個功能:

  1. 按照指定的維度劃分資料集;
  2. 對圖表進行排版。

G2支援以下的分面型別:

分面型別 說明
rect 預設型別,指定 2 個維度作為行列,形成圖表的矩陣。
list 指定一個維度,可以指定一行有幾列,超出自動換行。
circle 指定一個維度,沿著圓分佈。
tree 指定多個維度,每個維度作為樹的一級,展開多層圖表。
mirror 指定一個維度,形成映象圖表。
matrix 指定一個維度,形成矩陣分面。

注意,在我的程式碼中,為了簡化使用,只支援list和rect,當繫結一個欄位的時候用list,繫結兩個欄位的時候用rect。

除了上面提到的元素,當然還有許多其它的元素我們沒有包含和支援,例如:座標軸,圖例,提示等等。

關於圖形的語法的更多內容,請參考這裡

生成圖形語法的核心程式碼如下:

這裡有幾點要注意:

  • 使用JS的模版字串可以有效的構造程式碼片段
  • 使用eval執行構造好的語法驅動的程式碼來響應select的change事件,以獲得良好的互動性。在生產環境,要注意該方法的安全性隱患,因為純前端,eval能帶來的威脅比較小,生產中,可以把這個執行放在安全的沙箱中執行
  • 你需要理解圖形語法,並不是任意的組合都能驅動出有效的圖形。

這裡對於select2的多選,有一個小的提示,在預設情況下,多選的順序是固定的順序,並不依賴選擇的順序,然而許多圖形語法和欄位的順序有關,所以我們使用如下的方法來相應select的選擇事件。

這樣做就是每次選中後,把當前選中的專案移到資料最後的位置。

 

一些例子

好了,下面我們就來看一些例子,瞭解一下如何使用圖形語法來分析和探索資料。

 

Iris資料集散點圖

用500行純前端程式碼在瀏覽器中構建一個Tableau

圖形語法:

 

Car資料集折線圖

用500行純前端程式碼在瀏覽器中構建一個Tableau

圖形語法:

切換到極座標:

用500行純前端程式碼在瀏覽器中構建一個Tableau

圖形語法:

 

Berkeley資料柱狀圖

用500行純前端程式碼在瀏覽器中構建一個Tableau

資料處理:

圖形語法:

 

Berkeley資料堆疊柱狀圖

用500行純前端程式碼在瀏覽器中構建一個Tableau

資料處理:

圖形語法:

 

Berkeley資料餅圖

用500行純前端程式碼在瀏覽器中構建一個Tableau

資料處理:

圖形語法:

 

Berkeley資料分面的應用

用500行純前端程式碼在瀏覽器中構建一個Tableau

圖形語法:

更多的分析圖形留給大家去嘗試

 

總結

本文分享了一個利用純前端技術構建一個類似Tableau的BI應用的例子,整個程式碼統計:

  • JS 370 行 JS6
  • HTML 69 + 9 + 5 = 83
  • CSS 21

總計474 行,用這麼少的程式碼就能完成一個看上去還不錯的BI工具,還算不錯吧。當然這裡主要是由於開源社群提供了這麼多好的前端庫以供應用,我要做的僅僅是讓它們有效的工作在一起。這個只能算是個原型,從功能和質量上來說都不成熟,但是能在瀏覽器中不借助任何的伺服器來實現BI的資料分析功能,應該會有很多人想要在自己的應用中嵌一個吧?

結合我之前分享的TensorflowJS的文章,下面一步可能是加入預測功能,為資料分析加入智慧,前端應用的前景,不可限量!

 

參考

相關文章