Tagcloud Font Distributor

By Hawkee on Nov 18, 2005

This will assign font sizes to tags based on their counts. It tries to evenly distribute the font sizes among the tags while keeping all tags with the same counts under the same font size. The data needs to be in the following format:

$tag[tag_name] => Tag Name
$tag[tag_count] => Number of instances of this tag
$tag[tag_class] => Resulting class name, ex: tag1, tag2

Please note that this does not work with a class object. This was designed to work with an array only.

Once you create an array of these objects, you can feed them to the cloud_tags() function which will assign each $tag with a tag_class based on it's tag_count and the overall number of font sizes and tags. The return result is the array sorted aphabetically with each tag_class properly assigned.

You may change the $tag_sizes variable to indicate fewer or more font sizes. You can create your css classes in the format tag1, tag2, tag3, etc. or use the CSS found in the screenshot: Tagcloud CSS Stylesheet

$tags = cloud_tags($tags);

Screenshot:
Image

/****************************************************************************************/
// Sorts a list of tags by their count ascending.

function tag_asort($tag1, $tag2)
{
   if($tag1[tag_count] == $tag2[tag_count])
   {
       return 0;
   }
   return ($tag1[tag_count] < $tag2[tag_count]) ? -1 : 1;
}

/****************************************************************************************/
// Sorts a list of tags alphabetically by tag_name

function tag_alphasort($tag1, $tag2)
{
   if($tag1[tag_name] == $tag2[tag_name])
   {
       return 0;
   }
   return ($tag1[tag_name] < $tag2[tag_name]) ? -1 : 1;
}

/****************************************************************************************/
// Assigns classes to each given tag.

function cloud_tags($tags)
{
    $tag_sizes = 7;

    usort($tags, "tag_asort");
    if(count($tags) > 0)
    {
        // Start with the sorted list of tags and divide by the number of font sizes (buckets).
        // Then proceed to put an even number of tags into each bucket.  The only restriction is
        // that tags of the same count can't span 2 buckets, so some buckets may have more tags
        // than others.  Because of this, the sorted list of remaining tags is divided by the
        // remaining 'buckets' to evenly distribute the remainder of the tags and to fill as
        // many 'buckets' as possible up to the largest font size.

        $total_tags = count($tags);
        $min_tags = $total_tags / $tag_sizes;

        $bucket_count = 1;
        $bucket_items = 0;
        $tags_set = 0;
        foreach($tags as $key => $tag)
        {
            $tag_count = $tag[tag_count];

            // If we've met the minimum number of tags for this class and the current tag
            // does not equal the last tag, we can proceed to the next class.

            if(($bucket_items >= $min_tags) and $last_count != $tag_count and $bucket_count < $tag_sizes)
            {
                $bucket_count++;
                $bucket_items = 0;

                // Calculate a new minimum number of tags for the remaining classes.

                $remaining_tags = $total_tags - $tags_set;
                $min_tags = $remaining_tags / $bucket_count;
            }

            // Set the tag to the current class.

            $tags[$key][tag_class] = 'tag'.$bucket_count;
            $bucket_items++;
            $tags_set++;

            $last_count = $tag_count;
        }
        usort($tags, 'tag_alphasort');
    }

    return $tags;
}

Comments

Sign in to comment.
GuitarMasterx7   -  Dec 08, 2010

ah i see. thank you;3

 Respond  
sean   -  Dec 08, 2010

@GuitarMasterx7: yes, you could use this regardless of what IDE you use.

This is a PHP snippet, so you would need to add it to a .php file. You'd also want to wrap the code within the respective <?php ?> tags.

 Respond  
GuitarMasterx7   -  Dec 08, 2010

i know this is old butttttt
would this work in Adobe Dreamweaver CS3?

and where would i put this...

 Respond  
nyfalcon   -  Jun 12, 2007

Wow this is really helpful thanks

 Respond  
Hawkee   -  Mar 21, 2007

Furby, you need to create a database of tags / keywords and add up the number of items for each keyword. Once you\'ve built an array with this information use the format given above to determine CSS tags for each item. Here is the CSS we use here at Hawkee:

http://www.hawkee.com/snippet/2495/

 Respond  
F*U*R*B*Y*   -  Mar 20, 2007

Hawkee, can you give an example on how to use this please? :) it looks great and i am yearning to use it on my website :P

 Respond  
an_goodboy2000   -  May 19, 2006

Hi phpotter
can u give an example of how to extract the tags and class from the returned array and display a basic tag cloud for the test data you have given

thnx
Regards

 Respond  
phpOtter   -  Apr 20, 2006

how to use the cloud_tag class (see post below for class source):

// create some fake input

$tags = array();
$tempTag[tag_name] = \'ajax\';
$tempTag[tag_count] = 3;
$tags[] = $tempTag;
$tempTag[tag_name] = \'mysql\';
$tempTag[tag_count] = 3;
$tags[] = $tempTag;
$tempTag[tag_name] = \'linux\';
$tempTag[tag_count] = 1;
$tags[] = $tempTag;
$tempTag[tag_name] = \'php\';
$tempTag[tag_count] = 6;
$tags[] = $tempTag;

// instantiate a cloud
$cloud = new cloud_tag();

    // the class already has defaults, but let\'s override them for fun

$cloud->set_label(\'cloud\'); // css classes will be cloud1, cloud2, etc.
$cloud->set_tagsizes(7);    // 7 font sizes will be used

$newtags = $cloud->make_cloud($tags); // make a tag cloud
 Respond  
phpOtter   -  Apr 20, 2006

Great snippet. I created a class around it to make management easier and to let you set the number of buckets (fonts) and the base css class name. How to use in the next post.

class cloud_tag
{
// constructor. init our variables
function cloud_tag()
{
$this->tag_label = \"tag\";
$this->tag_sizes = 7;
}

// set the label for the css class
function set_label($label)      {$this->tag_label = $label;}

// set the number of buckets
function set_tagsizes($sizes)   {$this->tag_sizes = $sizes;}

// create a cloud tag
function make_cloud($tags)
{

    usort($tags, array($this,\'tag_asort\'));
    if(count($tags) == 0) return $tags;

    // Start with the sorted list of tags and divide by the number of font sizes (buckets).
    // Then proceed to put an even number of tags into each bucket.  The only restriction is
    // that tags of the same count can\'t span 2 buckets, so some buckets may have more tags
    // than others.  Because of this, the sorted list of remaining tags is divided by the
    // remaining \'buckets\' to evenly distribute the remainder of the tags and to fill as
    // many \'buckets\' as possible up to the largest font size.

    $total_tags = count($tags);
    $min_tags = $total_tags / $this->tag_sizes;

    $bucket_count = 1;
    $bucket_items = 0;
    $tags_set = 0;
    foreach($tags as $key => $tag)
    {
        $tag_count = $tag[tag_count];

        // If we\'ve met the minimum number of tags for this class and the current tag
        // does not equal the last tag, we can proceed to the next class.

        if(($bucket_items >= $min_tags) and $last_count != $tag_count and $bucket_count < $this->tag_sizes)
        {
            $bucket_count++;
            $bucket_items = 0;

            // Calculate a new minimum number of tags for the remaining classes.
            $remaining_tags = $total_tags - $tags_set;
            $min_tags = $remaining_tags / $bucket_count;
        }

        // Set the tag to the current class.
        $tags[$key][tag_class] = $this->tag_label.$bucket_count;
        $bucket_items++;
        $tags_set++;

        $last_count = $tag_count;
    }

    usort($tags, array($this,\'tag_alphasort\'));

    return $tags;
}

/*-------------------------------------------------------
            internal-use-only below here
-------------------------------------------------------*/

// sorts a list of tags by their count ascending.
function tag_asort($tag1, $tag2)
{
   if($tag1[tag_count] == $tag2[tag_count]) return 0;
   return ($tag1[tag_count] < $tag2[tag_count]) ? -1 : 1;
}

// sorts a list of tags alphabetically by tag_name
function tag_alphasort($tag1, $tag2)
{
   if($tag1[tag_name] == $tag2[tag_name]) return 0;
   return ($tag1[tag_name] < $tag2[tag_name]) ? -1 : 1;
}

/*-------------------------------------------------------
                member variables
-------------------------------------------------------*/

var $tag_label;     // the css base class name
var $tag_sizes;     // number of buckets (font sizes)

}

 Respond  
sunnyc   -  Mar 28, 2006

Pomppu, could you please help us how to implement this on my site. Sorry I cannot provide the URL to my site as it is on a test bed internally behind the firewall.

I got machine setup with fedora core 4 running apache, mysql, perl, and php.

I am not a php programmer myself and i know little bit about CGI scripting. Your help will be much appreciated.

 Respond  
Hawkee   -  Mar 28, 2006

This should do the trick here:

require(\"databaseconnection.php\");

$tags=array();

$sql = \"SELECT tag, COUNT(tag) as count FROM links_tags GROUP BY tag ORDER BY count\";
$result = mysql_query($sql);

while ($rowInfo = mysql_fetch_assoc($result))
{
$tempTag[tag_name] = $rowInfo[\'tag\'];
$tempTag[tag_count] = $rowInfo[\'count\'];
$tags[] = $tempTag;
}

$tags = cloud_tags($tags);

 Respond  
Hawkee   -  Mar 28, 2006

pomppu, this code does not use a class. You just need to create an array. So in your code use $tempTag[tag_name] = $rowInfo[\'tag\'] and forget creating a new tag() object. This should solve your problem.

 Respond  
an_goodboy2000   -  Mar 28, 2006

ya the hawkee guys should be able to help us out here since they are already using this code? pomppu am going through your code if i find the soln will let u know

 Respond  
sunnyc   -  Mar 28, 2006

can hawkee programers please help popppu as i see you have implemented this on your site. your help is much appreciated.

 Respond  
pomppu   -  Mar 28, 2006

I can post thorough and easy-to-understand instructions on how to use this as soon as someone more knowledgeable points out what the problem with my attempt is. I\'m pretty sure it is a very small thing.

 Respond  
sunnyc   -  Mar 28, 2006

Its good the code is published but as an_goodboy2000 requested can someone please explain how to use this code so even we can learn and implement it on our site.

 Respond  
pomppu   -  Mar 28, 2006

I\'ve been banging my head onto a wall while trying to get this to work. I cannot provide a working sample code, but here\'s a try so if anyone can tell me what\'s wrong with my attempt, then there\'s the sample for you too, an_goodboy2000.

My problem is that there is something wrong with the array of objects I\'m creating. I get an error message for each tag object in my array saying: \"Warning: Cannot use a scalar value as an array in /home/[removed]/links.php on line 103\"

The line 103 looks like this: $tags[$key][tag_class] = \'tag\'.$bucket_count;

This is my code:

require(\"databaseconnection.php\");

class tag {
var $tag_name;
var $tag_count;
var $tag_class;
}

$tags=array();

$sql = \"SELECT tag, COUNT(tag) as count FROM links_tags GROUP BY tag ORDER BY count\";
$result = mysql_query($sql);

while ($rowInfo = mysql_fetch_assoc($result))
{
$tempTag=new tag();
$tempTag->tag_name = ($rowInfo[\'tag\']);
$tempTag->tag_count = ($rowInfo[\'count\']);
$tags[]=$tempTag;
}

cloud_tags($tags);

Could someone please show me what I\'m doing wrong. Best regards and thanks in advance.

 Respond  
an_goodboy2000   -  Mar 27, 2006

Can u provide a sample on how to use this to create a tag cloud

 Respond  
Are you sure you want to unfollow this person?
Are you sure you want to delete this?
Click "Unsubscribe" to stop receiving notices pertaining to this post.
Click "Subscribe" to resume notices pertaining to this post.