You should have seen the aesthetic tag cloud above somewhere on the web. It originates from the famous Wordle words cloud (closed source). For the past few days, I have ported an open source Java class to ActionScript and able to render the tag cloud in Flash as seen above. Please refer to this article to have the Java author explain the basic of the algorithm. (Thank Pierre Lindenbaum for the nice implementation)
For my AS3 port, I’ll leave the source code explain itself (mentioned below); but I can commend that Flash is very suitable for such visual tasks as it has built-in classes for drawing and object positioning. Some notable works for the Flash adaptation are:
- Checking for closely-fit bounds of the text on TextField (simple getBounds() will leave you some unwanted padding around the TextField object).
I would like to thank Thu Hoang, my dear colleague, who helped fixing this perfect bounds implementation. - Deploy some pixel perfect collision detection approaches and try them. However the result is extremely slow and somehow inaccurate. I leave this for later improvement.
- As the process of collision testing and word placing cost a lot of CPU power, the Flash application usually hang for several seconds when rendering the tag cloud. To prevent this, I have split the process into multiple ENTER_FRAME events in order to eliminate the hang and resulted in a word-appearing animation.
- The class doesn’t care about scaling to fit the viewport yet. I intend to take care of that later.
I would like to open source the whole project but that is not possible because I have spent some of my company time doing the porting (It also come from a request of a commercial project). But I’m pleased to share the basic porting of the Java class which you can view it here (or check out the SVN here)
The open source Wordle tag cloud is the basic porting of the Java class which still run on single loop (no animation and still hang). But to split the process into multiple frames is simple OR you can deploy a pseudo-threading library. There are plenty of rooms for you to improve. (See the open source demo here.)
There is a native AS3 implementation as you can find here. I found the vertical/horizontal case of this implementation doesn’t look very good (and my request doesn’t care about free angle) so I decided to go with this Java class.
On a side note, when testing the single loop demo, I realized that the Flash Player on Linux (~2000ms) runs approximately 4 times slower than the Windows’ counter part (~500ms). Holy cow!
Updated 2013-04-04: I have uploaded this demo on Github sometimes ago. Please visit the Github repo. In this repo, I have also committed the part that was closed: multi-frame calculation (to avoid blocking script). However, this part remains closed source. You can read it for inspiration only. If you want to use the closed part (Main.as, WordleAS3.as), please seek permission from my ex-employer (noted as copyright holder in the source).
[Vietnamese tag: Đám mây tag Wordle viết bằng ActionScript 3]
It's nice to see that someone is using my code ;-)
ReplyDeleteI'm about to commend on your article to inform about my port but you have noticed it already. ;)
ReplyDeleteHi, thanks for putting your code online! i'm currently using your code (to try to create multi-wordles, and making it asynchronously). am i correct that your code (the while (!done)-loop in fact doesn't follow a spiral (increment both radius & degree a bit at the same time) but actually is testing on all circles with all radiuses?
ReplyDeletestill, excellent work though, many thanks for that!
You are correct. The test is not on a spiral increment of radius but just a random start angle. The reason for a random start angle is the texts will scatter around more evenly.
ReplyDeleteBesides, here's a hint to make the calculation script non-blocking: you can split the tasks done in that while loop into multiple ENTER_FRAME event. Doing so, the texts will appear one by one.
hi Trọng,
ReplyDeletethankks for open sourcing this, looks great.
I noticed that the words with the highest weight always are at the edge of the cloud. is that something i could change easily?
John
Hi John,
ReplyDeleteThe demo (which is temporarily out due to failed FileDen service) is randomizing the words order. Because larger words is not likely to fit in small free space so they have tendency to be placed at the edge. I think you can try the sorting in which largest word appear first. This will make sure large work will be placed in the middle of the cloud.
Oh you actually have adoSortType var with a switch stement in there ;)
ReplyDeleteThanks for your share. I would like to ask, how would us solve the character problem? As you stated in the codes one of your file, text.replace deletes all non-english characters. Is it possible to get latin-extended characters?
ReplyDeleteHi there,
ReplyDeleteThat line is basically a safeguard to remove weird characters, and it is over-simplified. If you can make sure your input string is under control, then just remove the text.replace line or update the pattern with allowed characters.