JavaScript tag cloud rewrite

It's interesting to see "cloud" of things and in the recent days I hacked something up for Plurk:

I reused delicious'es tag cloud generation script, which looks something like this:

var tag_cloud = "";

var ta = 0, tz = 11;
function s(a,b,i,x){
    if(a>b){
        var m=(a-b)/Math.log(x),v=a-Math.floor(Math.log(i)*m);
    }
    else{
        var m=(b-a)/Math.log(x),v=Math.floor(Math.log(i)*m+a);
    }
    return v;
}

var ca=[51,102,102],cz=[0,102,255],c=[]
    tag_cloud += '<div class="plurk-tags"><ul class="plurk-cloud">';

var TAGS = ${ json(tags) };
var WORDS = ${ json( sorted(tags.keys()) ) };

map(WORDS, function(t)  {
    for (var i=0;i<3;i++)
        c[i] = s(ca[i], cz[i], TAGS[t]-ta, tz);
    var fs = s(12, 35, TAGS[t]-ta, tz);

    var tag = encodeURIComponent(t).replace('%2F','/');
    tag_cloud += '<li style="font-size:'+fs+'px;line-height:1;">';

    tag_cloud += '<span style="color:rgb('+c[0]+','+c[1]+','+c[2]+')">'+t+'</span> ';
    tag_cloud += "</li>";
});

tag_cloud += "</ul></div>";

$('tags').innerHTML = tag_cloud;

This code works, but it's mostly write once code, because of these things:

  • The global scope is polluted
  • The variables are <= 2 char long (a disaster for rewrites and general understanding)
  • DOM is built as a string manipulation
  • String concatenations are used

Here is my rewrite that fixes some of these things:

TagCloud = {
    //Color hues
    ca: [51,102,102], 
    cz: [0,102,255],

    min_font_size: 12,
    max_font_size: 35,

    generate: function(all_tags, all_words) {
        var self = this, colors=[], font_size;

        var ul = UL({c: 'plurk-cloud'});

        map(all_words, function(t)  {
            for (var i=0; i<3; i++)
                colors[i] = self._score(self.ca[i], self.cz[i], all_tags[t]);

            font_size = self._score(self.min_font_size, self.max_font_size, all_tags[t]);

            var color_attr = 'color:rgb('+colors[0]+','+colors[1]+','+colors[2]+')';
            var li = LI({s: 'font-size:'+ font_size + 'px'},
                SPAN({s: color_attr}, t)
            );

            ACN(ul, li, ' ');
        });

        return DIV({c: 'plurk-tags'}, ul);
    },

    _score: function(a, b, counts) {
        //reducer impacts color and font size, choosing a bigger will make the font smaller
        var reducer = 11;
        var m = Math.abs(a-b) / Math.log(reducer);

        if(a > b)
            return a - Math.floor(Math.log(counts) * m);
        else
            return Math.floor(Math.log(counts) * m + a);
    }
}

var TAGS = ${ json(tags) };
var WORDS = ${ json( sorted(tags.keys()) ) };
RCN($('tags'), TagCloud.generate(TAGS, WORDS));

You are free to comment any additional rewrites (if you got any ;)). And remember:

If you have some code that you want me to review/rewrite, then send it to amix _at_ amix.dk.
You can be anonymous if you wish.

Code rewrite · JavaScript 13. Sep 2008
© Amir Salihefendic. Powered by Skeletonz.