Word Cloud – Open source “Wordle” in HTML5

中文:HTML5 文字雲現在是開源專案,歡迎到 Github 索取程式碼。自從公開之後新增的功能有隨機旋轉文字、彩色文字、支援 IE9 與 iPhone/iPad(很慢,不建議使用)。

HTML5 Word Clouds is a HTML5 technical demo that generate a Java-based Wordle-like word cloud.

Under the hood, functions are devided into a library and two jQuery plug-ins:

  • jQuery.getContent that fetch text remotely or locally using FileReader API
  • WordFreq that run the text against Porter Stemming Algorithm (English) or N-gram analysis (Chinese) in Web Workers
  • Finally, jQuery.wordCloud draws beautiful word cloud on <canvas>

For Mobile Safari and IE9 that doesn’t support Web Workers, I wrote Simulated Worker that put the worker script into an iframe scope (instead worker scope).

You are welcome to play around, grab the source code and run the testcases to see their capabilities.

Simulated Web Workers

So you put your complicated computation in Web Workers, but you just realized the computation is not that complicated at all. Also, you denied the browsers without web workers to ever running your hard work – Mobile Safari, all IEs up to version 9.

Here is the solution I took, something might be useful to you: Simulated Web Workers – a library that creates a pseudo-web worker (that runs at fore-ground), while expose the same interfaces. Well, almost.

By almost, I mean the following:

  • Instead of calling postMessage() to send the result, in IE you must call workerPostMessage() – because IE doesn’t allow me to overwrite the aforementioned function.
  • Since anything runs at fore-ground right now, they are subjected to runaway Javascript timer imposed by browsers – the while(true) example given by Wikipedia won’t work. The setTimeout() trick however would make it work again (in a not-so-efficient way) – please check the library tests.

You could say Simulated Web Workers is like exCanvas for canvas, but of course the interfaces of web workers are not that many. Anyway, have fun with your next web workers project.

HTML5 文字雲

Update: Here is the introduction in English.

猜猜看這是哪個 blog 的最常出現的詞彙?

文字雲是最近在嘗試的 HTML5 瀏覽器 Demo,目標是使用前端技術來完成 Java 撰寫的 Wordle,順便可以拿來測試瀏覽器效能,以及分析一些文字來源。

目前程式可以接受硬碟裡的檔案或是 RSS Feed 的文字(從 Google Feed API 拉資料),經過詞頻分析,以出現的數量來決定文字大小,排進 HTML5 canvas,像這是這個 blog 的分析結果:


最前面貼的第一張圖則是來自地圖會說話,其他像是 New York Times 的文字雲可以看出最近的新聞 buzz word 是什麼。

文章詞頻分析

中文用的是很標準的 N-gram(我做到 N=6),把字組切出來算頻率。英文的話則引用了資料庫常用的 Porter Stemming Algorithm 來歸一化字的變形(複數型、正在進行式等等)。想起來中文的分析還真的是知難行易,完全不做任何過濾效果就會很好(後來有濾掉一些不是詞的字組就是),而且唯一的 stop word 只有「的」。

測試的時候懷疑瀏覽器執行這些文字操作的效能,所以就把這段程式碼放進 Web Workers。放完發現效能沒有提昇多少,真正卡住的東西是畫 canvas … 不過還是保持這樣,因為使用者有可能會放大量文字進來(但只差 Web Workers 就可以執行的 IE9 就抱歉了)

使用前端額外的好處是使用者可以載入自己的檔案來分析,而且檔案不需要傳到主機上。測試的時候曾經跟別人要了在學校寫的報告,圖像很好玩。大部分的部落格最大的詞都是「可以」,不知道是不是口語中文的現象。

文字雲圖像

圖則是仰賴 canvas 的填入文字(fillText)功能。有一個二維 Array 來儲存哪裡還有空間的資訊,每次填入文字之後再用 getPixelData 偵測文字筆劃的位置,更新 Array。在 Chrome 上面,文字大小會受設定裡面的最小字型大小的影響,所以最後會有很多不太小的小字。另外就是 Firefox 的 getPixelData 效能有問題,只有別人的 1/6 甚至更慢,為了避免瀏覽器卡死只好放了偵測所花時間,超過就跳出警告訊息的程式碼。Firefox 另外還有一個 canvas 有更新但是卻不顯示結果的 bug,不是很 reproducible 而且好像每台電腦行為都不一樣,只好先放著(canvas 的效能和問題都跟硬體加速有關)。

使用者介面

這東西為何會被我放在硬碟裡快一個月就是因為 UI 搞不定 orz … 做了兩個版本,每次 show 給別人看的時候都很容易操作錯誤;現在這個是 2.5 版,流程變成仰賴網址的 Hash 和 onhashchange 事件。對於寫出有用但是 UI 失敗的程式,我也感到很無奈 orz

接下來?

歡迎大家玩玩看。字頻分析和文字雲兩個功能都包成 library 了,拿去做其他應用應該很方便。不過我希望先保留程式碼兩個星期,之後再公開;目前網站上的是 minified script。

有空的話會想要支援更多自然語言(日文、韓文等),還有拿字頻做其他 visual(或是 audio?Bob 給了一個的點子,我才注意到其實字頻分布跟 FFT 轉換後的聲音頻譜還滿像的?)

最後,喜歡的話賞我一個讚吧 XD 寫不少東西但是不太知道反應,也不知道要去哪裡推。