p5.js Cover

網頁資料視覺化常使人感到挫折 - 各種不同規格、瀏覽器支援、技術細節的瑣碎,往往令初學者為之卻步。p5.js 包裝所有的技術細節而提供了一組專用函式庫,讓不同領域的開發者可以更專心於視覺化本身。

p5.js 事實上是 Processing 的 JS 移植版。2001 年,MIT MediaLab 的 Casey Reas and Benjamin Fry 考量到技術細節的問題,開發了 Processing 語言來包裝資料視覺化外的旁枝末節,讓開發者可以專心於視覺化本身。p5.js 做為 Processing 的移植,完整的採用了Processing 的函式庫介面,並使用 Javascript 做為開發語言,讓原本使用 Javascript 的開發者不再需要另外學習一套程式語言。

p5.js 的邏輯相當簡單,一段 p5.js 程式碼包含初始化與繪圖兩個階段,你只要定義對應的函式,程式便會自行運作:

  function preload() { /* 載入資料 */ }
  function setup() { /* ... 初始化程式碼, 資料載入完後執行 */ }
  function draw() { /* 繪圖程式碼,會自動不斷的執行 */ }

讓我們來想像製作一個簡單的統計圖表 - 長條圖的過程:

  1. 在 preload 中載入資料
  2. 在 draw 中依資料繪出長條圖

其中所需要的對應功能,例如載入資料或繪製矩形,即利用 p5.js 包裝好的函式庫來實作。例如,載入資料可以使用 loadJSON 函式,繪製矩形可以使用 rect 函式。馬上就來實作看看:

  var data = null;
  function preload() {
    loadJSON("index.json", function(it) { data = it; }); /* 載入資料 */
  }

  function draw() {
    if(data) {
      for(i=0;i<data.length;i++) {
        rect(10, i*10, data[i]+10, 8); /* 畫出來 */
      }
    }
  }

以資料 [20, 5, 40, 15, 33] 為例,執行結果大概像這個樣子:

p5js Bar Chart Example

要做到更複雜的事,可以參考 p5.js 的 Reference ,裡面記載了有什麼樣的函式可以使用,包括了顏色、輸入裝置(滑鼠、鍵盤等)、繪圖、寫字等等約 14 個類別的函式。舉例來說,下面為實作一個圓餅圖的程式碼:

  var data = [20,5,40,15,33]; /* 為了簡潔, 資料預先寫好 */
  var piedata = [], piecolor = [48,96,144,192,240];
  var mouseAngle = 0, pieDelta = 0, hover = 0;

  function setup() {
    createCanvas(640,480); /* 設定畫布的寬高 */
    total = data.reduce(function(a,b){ return a+b; }, 0);
    for(var i=0,count=0;i<data.length;i++) { /* 轉換資料給圓餅圖用 */
      piedata.push([Math.PI * 2 * count / total, Math.PI * 2 * (count + data[i]) / total]);
      count += data[i];
    }
  }

  function draw() {
    clear(); /* 每次重畫都清除畫布 */
    for(var i=0,dx=0,dy=0;i<piedata.length;i++,dx=0,dy=0) {
      fill(piecolor[i%5]);
      /* 將滑鼠上的圓餅浮出 */
      if(mouseAngle >= piedata[i][0] && mouseAngle < piedata[i][1]) {
        dx = Math.cos((piedata[i][0] + piedata[i][1])/2) * 10;
        dy = Math.sin((piedata[i][0] + piedata[i][1])/2) * 10;
      }
      /* 繪出圓餅 */
      arc(320 + dx, 200 + dy, 300, 300, piedata[i][0], piedata[i][1], PIE);
    }
  }

  /* 滑鼠移動的時候,確認滑鼠相對圓餅中心的角度 */
  function mouseMoved() {
    mouseAngle = Math.PI / 2 - Math.atan((320 - mouseX) / (200 - mouseY));
    if(mouseY < 200) mouseAngle = mouseAngle + Math.PI;
  }

這段程式碼的執行結果如下:

若你對完整程式碼有興趣的話,原始碼可以在這裡找到。

Processing.js

事實上 Processing 除了 p5.js 這個實作以外,還有一個叫 processing.js 的工具,他同樣是將 Processing 移植到網頁上來。那麼 p5.js 與 processing.js 有什麼不同呢?

  • Live Translation vs Native Code : processing.js 即時將 Processing 使用的 PDE 檔轉成 Javascript 後再執行,而 p5.js 原生便是使用 Javascript 撰寫程式碼。
  • 由於 p5.js 直接使用 Javascript ,你也可以與任何其它的 Javascript 函式庫併用。

比方說,前例的圓餅圖顏色是寫死在程式碼中的,這時我們可以考慮與 tinycolor.js 或 D3.js 併用來產生顏色:

  var colormap = d3.scale.linear().domain([0,4]).range(["#f00","#0f0"]);
  ...
  fill(colormap(i%5));

其擴充性相對於 processing.js 可說是大上許多。

結語

這次我們簡單的玩了一下 p5.js ,並製作了兩種基本的統計圖表, p5.js 可說是相當容易上手。然而容易上手並沒有讓他變成很侷限的視覺化工具,相反的他其實仍然能夠做出相當不錯的互動式資料視覺化。例如 p5.js 官網上的這個例子 Flocking Visualization ,展示了個體規則對群體表現的影響,使用者除了觀賞網頁中的動畫外,也可以透過滑鼠拖曳來加入新的個體,實現互動的效果。

p5.js 相當適合給剛學會 Javascript 但對網頁技術還不是很熟的朋友,或者是做為視覺化課程中練習實作的一個套件。有興趣的朋友不妨到 p5.js 的官網上尋找更多的資訊。


Written by infographics.tw

發表迴響

你的電子郵件位址並不會被公開。 必要欄位標記為 *