In preceding post, I have talked about hiring tag could in your cnblog. It seems that works smoothly. But, there are still something we should not overlook, otherwise, you will have a BIG TAG LIST rather than tag cloud.

 

Still remember the code calculating the font size? To recall your memory, I will put it here again.

var fontSize = 0.8 + count / 10.0;

if (fontSize > 2) { 

    fontSize = 2; 

}

In the code above, 0.8 is the initial font size, 10.0 is the scaling factor, and we will firm the font size if it exceed 2. Here are the problems.

  1. This method is static because scaling factor is static.
  2. If all post counts under your tags exceed 12 (you know, 0.8 + 12 / 10.0 = 2), you will get a BIG TAG LIST rather than tag could.

What’s a BIG TAG LIST exactly? Well, I’ll show you an example.

ASP.NET MVC

Performance Tuning

IIS 6JavaScript

See? A BIG TAG LIST is fairly meaningless.

Since we found the flaws of original implementation, we need to find a way to dynamically calculate font sizes.

Oh wait, dynamically? What the heck shall I do?

Take it easy man, it is not that difficult for you. Let’s have a look at some basic equations.

 

Firstly, we want to make our function dynamic, we need a dynamic scaling factor, which is 10.0 in our previous code. The following equation shows how to get a dynamic proportion (p in equation).

image

 

Then, we can use the proportion to calculate font sizes dynamically by the following equation.

image

 

 

So far so good. Finally, let’s rewrite the code as following.

function applyTagCloud() {
    var matches = $('#MyTag').html().match(/<a(.*?<\/a>).*?\((\d+)\)/g);
    var minPostCount = 0, maxPostCount = 0;
    var minFontSize = 0.8, maxFontSize = 2;
    var tags = [], result = [];

    for (var i = 0, l = matches.length; i < l; i++) {
        var match = /<a(.*?<\/a>).*?\((\d+)\)/g.exec(matches[i]);
        var tag = { postLink: match[1], postCount: parseInt(match[2]) };
        minPostCount = Math.min(minPostCount, tag.postCount);
        maxPostCount = Math.max(maxPostCount, tag.postCount);
        tags.push(tag);
    }

    var p = (maxFontSize - minFontSize) / (maxPostCount - minPostCount);

    for (var i = 0, l = tags.length; i < l; i++) {
        var tag = tags[i];
        var fontSize = (tag.postCount - minPostCount) * p + minFontSize;
        result.push('<a style="font-size: ' + fontSize + 'em;"' + tag.postLink)
    }

    $('#MyTag').html(result.join(''));
}

 

I found something interesting during writing the code. I cannot reuse the Regex object like I did in previous post, otherwise, it will return null for some matches. So I have to claim regex /<a(.*?<\/a>).*?\((\d+)\)/g twice in the code.

 posted on 2011-02-06 22:04  助平君  阅读(1384)  评论(1编辑  收藏  举报