A Better Tag Cloud
Tagging is everywhere. Long considered a tedious task fit for librarians and taxonomy nerds, the process of assigning keywords to information has recently become near-ubiquitous for all manner of assets. Photos, websites, audio, comics, news and even browser extensions now enjoy an elevated status amongst the metadata'd. This tagging information is then displayed in what's commonly known as a "tag cloud". The standard tag cloud is a list of tags denoting popularity through point size. It has been hastily adopted by the masses as de rigeur and pretty much left at that. I think there are plenty of creative opportunites to display this data beyond the confines of simple typographic manipulation. So allow me to present, then, "a better tag cloud".
Initally, I was interested in seeing how I could use treemaps to display tagging data. But I soon found that treemaps become unreadable very quickly when you are dealing with large contiguous blocks of small objects (in this case, lots of single tags). There is no space to display the tag names and very little aesthetic appeal. They also take a fair amount of processing resources to render, which would be a barrier to in-browser rendering -- a feature I planned to implement. Tags really only offer one dimension (quantity) of plottable data, so I would miss out on one of the key features of treemaps -- their ability to represent hierachical groupings.
What ever my solution was going to be, I decided it had to look good. I wanted to use circles instead of rectangles, for a start, as groupings of them are much nicer than squares. I began to picture something along the lines of an Ishihara Plate:

These are seemingly random collections of points, used to determine color blindness. In my case, however, the area of each inner point would represent the quantity of like-named tags. I would still attempt to arrange them in a rough circular shape. There was also the possiblity of using colour to display the relation between tags, although this has yet to be implemented. Here then, is what I've come up with. This shows a tag cloud using data from my Penny Arcade Greasemonkey script, Pennypacker.
You can view the script in action here. Rendering is quite simple. Using either VML (in Internet Explorer) or Canvas to draw the tag circles, a circle is first placed in the center of the cloud. Circles are then fired at the cloud center from random angles, stopping only when they collide with another circle. Although it turns out this gives far from symetrical results, it does produce some nice-looking constructs. Tag names are displayed by mousing over a circle. Clicking it links through to the relevant tag page. Colour, including the highlight colour, is user definable, as is the order the tags are drawn (random, sorted in size from big to small and vice versa).
Download
The script is licensed under a Creative Commons License. It may be freely used for non-commercial projects, and may be modified provided those modifications are similarly shared. Please contact me regarding commercial use by email at ansonparker@gmail.com. Download tagcloud.js [20KB].
Usage
The tag cloud uses VML on Internet Explorer and Canvas on Firefox, Opera and Safari to render the tag circles. Support for VML requires you to add two lines to the page you want to run this script on. Firstly, you need to declare the VML namespace in your HTML tag. Add this xmlns:v="urn:schemas-microsoft-com:vml" to your html tag. You should end up with something that looks like this: <html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">. Secondly you need to declare the following style: v\:* { behavior: url(#default#VML); position: absolute}. You can add this to your style sheet, or simple insert it between a new style tag in your page.
You need to then create a container for the tag cloud to draw into. Usually a blank div is the way to go here. You may position and size this as you wish. Be sure to give it an id parameter so you can reference it later. As an example:
<div id="tagcloud" style="position: relative; width: 400px; height: 400px;"></div>
The tag cloud will be rendered in this div. There is no way to no exactly how big your tag cloud will end up. This is dependent on the number and size of the tags you are plotting. You may crop any circles that would go over the edges of the div by setting the overflow property to hidden.
Now you need to add the JavaScript code for the tag cloud. Take this block and modify it as needed:
<script src="../script/tagcloud.js"></script>
<script>
var tagcloud = new TagCloud(document.getElementById('tagcloudc'),'random');
tagcloud.addNode(new Node('the',13));
tagcloud.addNode(new Node('quick',12));
tagcloud.addNode(new Node('brown',15));
tagcloud.addNode(new Node('fox',20));
//...
tagcloud.draw();
</script>
Add your own tags where the tagcloud.addNode function calls are and you should be cooking with gas. The TagCloud function can take a number of additional parameters which allow you to customize it further:
TagCloud Constructor Reference
new TagCloud(container,sortstyle,colors,highlightcolors,urlstub)
container: This is the container element the tag cloud will be drawn into. As in the example above, pass a reference to the element itself, and not just the id.
sortstyle: There are 4 sorting options: "random", "ascending", descending" and "". This determines the order the tags will be drawn in. For example, "ascending" will cause the smallest tags to be drawn first resulting in the larger tags being furtherest from the center of the cloud. Sending through a blank string will render the tags in the order they were added.
colors: This is a single colour object, or an array of colours. If you pass an array, the each tags colour will be randomly selected from that array. A colour should be passed through as {r:0,g:0,b:0}. The number can be between 0 and 255. The previous example would result in black circles. For red circles you would send {r:255,g:0,b:0} or for a mix of blue and yellow circles, pass through the array [{r:255,g:255,b:0},{r:0,g:0,b:255}].
highlightcolors: Again, a single colour object, or an array of colours. This is the color or colors the circles will turn when you hover over them with the mouse.
urlstub: The base url clicking on a tag will link to. The name of the tag will be appended to this stub. So to link to a Technorati tag page you would pass through "http://technorati.com/tag/"


