Mikael's blog

A developers sixth time trying to maintain a blog

The Logarithmic Tag Cloud

A few days ago I sat down and tagged all my posts. Last night I decided to write a tag cloud.

The first try

I started out with a simple linear scale:

1
2
3
4
5
6
7
8
9
var countDiff = maxCount - minCount;
var sizeDiff = maxSize - minSize;
if (countDiff == 0) countDiff = 1; // no divide by zero
 
for (var i in doc) {
  var weight = (doc[i].value - minCount) / countDiff;
  var size = minSize + Math.round(sizeDiff * weight);
  model.tags.push( { tag: doc[i].key, size: size , count: doc[i].value } );
}
  • maxCount - The highest occurance of any tag.
  • minCount - The lowest occurance of any tag.
  • maxSize - The biggest allowed font size.
  • minSize - The smallest allowed font size.
  • doc[i].key - The name of the current tag.
  • doc[i].value - The occurance of the current tag.

It rendered, but something looked odd. The linear scale isn't really that pretty in a tag cloud. Especially not when a few tags (in my case #blog and #nodejs) has a substantially bigger weight than the rest. I wanted things to be readable with a minimum font size and a maximum font size set by me so that it couldn't break the page layout.

I fiddled around for a while with a few other (not so successful) algorithms and then I almost gave up.

Logarithms to the rescue

I finally thought of the logarithmic scale and after a couple of attempts it looked like my idea of a nice tag cloud.

1
2
3
4
5
6
7
8
9
var countDiff = Math.log(maxCount) - Math.log(minCount);
var sizeDiff = maxSize - minSize;
if (countDiff == 0) countDiff = 1; // no divide by zero
 
for (var i in doc) {
  var weight = (Math.log(doc[i].value) - Math.log(minCount)) / countDiff;
  var size = minSize + Math.round(sizeDiff * weight);
  model.tags.push( { tag: doc[i].key, size: size , count: doc[i].value } );
}

If you haven't noticed it in the top menu yet you can check it out here.

by Mikael Lofjärd
Comments
There are no comments for this post yet.

Name:

Home page:

Comment: