Nik's Technology Blog

Travels through programming, networks, and computers

Create a jQuery Tag Cloud from RSS XML Feed

I previously created a jQuery Blogger Template Category List Widget to retrieve blog categories from a Blogger.com RSS feed and create a list of links which click through to Blogger label pages.

I've now taken this code a step further and modified it to calculate the number of times each category/tag occurs enabling me to create a tag cloud from the data, like the one below.

 

Before I explain the code I wrote to make the tag cloud I'll go through the solution to a bug I found with the original categories code.

You may recall this snippet of code where I iterate through each post and then each category of each post, finally, when all the categories have been added to the array I sort them prior to de-duping them.

$.get('/blog/rss.xml', function(data) {
//Find each post
        $(data).find('item').each(function() {
//Get all the associated categories/tags for the post
            $($(this)).find('category').each(function() {
                categories[categories.length] = $(this).text();
            });
        });
        categories.sort();

I later refactored the code removing the $(data).find('item').each iteration which wasn't required since find('category') will find them all anyway.

I then discovered that the JavaScript .sort() function was case-sensitive which resulted in lower case categories being placed at the end of the list, causing problems when I de-dup them.

So the rewritten snippet of code became:

$.get('blog/rss.xml', function(data) {
     //Find each tag and add to an array
     $(data).find('category').each(function() {
         categories[categories.length] = $(this).text();
     });
     categories.sort(caseInsensitiveCompare);

where caseInsensitiveCompare refers to a JavaScript compare function:

function caseInsensitiveCompare(a, b) {
    var anew = a.toLowerCase();
    var bnew = b.toLowerCase();
    if (anew < bnew) return -1;
    if (anew > bnew) return 1;
    return 0;
}

Creating the Tag Cloud jQuery Code

I start off as before fetching the XML, adding all the categories/tags from the RSS feed to a JavaScript array, then sorting them.

But I needed a way to store, not only the tag name, but the number of times that tag is used on the blog (the number of times the category appears in the feed).  For this I decided to use a multi-dimensional array which would essentially store the data in a grid fashion e.g.

Tag Name Count
ASP.NET 5
Accessibility 2
Blogging 15
jQuery 2

 

The de-dup loop from my previous categories script now performs two jobs, it removes the tag duplicates and creates a count of each tag occurrence.

Once the multi-dimensional array has been populated, all that's left to do is iterate through the array creating the HTML necessary to build the tag cloud, followed by appending it to a DIV tag with an ID="bloggerCloud" on the page.

Note the calculation I perform to get the tags appearing a reasonable pixel size ((tagCount * 3) + 12).

$(document).ready(function() {
    var categories = new Array();
    var dedupedCategories = [];
    $.get('blog/rss.xml', function(data) {
        //Find each tag and add to an array
        $(data).find('category').each(function() {
            categories[categories.length] = $(this).text();
        });
        categories.sort(caseInsensitiveCompare);
        //Dedup tag list and create a multi-dimensional array to store 'tag' and 'tag count'
        var oldCategory = '';
        var x = 0;
        $(categories).each(function() {
            if (this.toString() != oldCategory) {
                //Create a new array to put inside the array row 
                dedupedCategories[x] = [];
                //Store the tag name first 
                dedupedCategories[x][0] = this.toString();
                //Start the tag count 
                dedupedCategories[x][1] = 1;
                x++;
            } else {
                //Increment tag count
                dedupedCategories[x - 1][1] = dedupedCategories[x - 1][1] + 1;
            }
            oldCategory = this.toString();
        });
        // Loop through all unique tags and write the cloud
        var cloudHtml = "";
        $(dedupedCategories).each(function(i) {
            cloudHtml += "<a href=\"/blog/labels/";
            cloudHtml += dedupedCategories[i][0] + ".html\"><span style=\"font-size:" + ((dedupedCategories[i][1] * 3) + 12) + "px;\">";
            cloudHtml += dedupedCategories[i][0] + "</span></a> \n";
        });
        $('#bloggerCloud').append(cloudHtml);
    });
    return false;
});

Since building this script I've now gone one step further and created a jQuery plug-in based on this code.  For more details and the source code see my jQuery Blogger.com Tag Cloud Plugin page.

Comments are closed