How do I create a tag cloud from a query?

A tag cloud is a list of tags where size and color reflects popularity- the more often a tag is used the larger and perhaps more colorfully it will be displayed in the cloud.

Say for example you want to create a dynamic tag cloud of links based on a list of categories that you have stored in a database. Once you have queried your data, the basic idea is to dynamically set the css font-size of your displayed tag text based on how many hits your query returned for that particular tag.

The following code sample shows how a tag cloud can be created based on a query of tags and their hit counts. Special thanks to Steven Erat http://www.talkingtree.com/blog/index.cfm/2005/11/15/TagCloudPod for contributing the majority of this code.

<!--- first we will statically populated a fake query with some test data.--->
<cfset tags = queryNew("tag,tagCount")>
<!--- Make 5 rows in the query--->
<cfset newRow = queryAddRow(tags, 5)>
<!--- Set the values of the cells in the query --->
<cfset temp = querySetCell(tags, "tag", "ColdFusion", 1)>
<cfset temp = querySetCell(tags, "tagCount", "100", 1)>
<cfset temp = querySetCell(tags, "tag", "Flex", 2)>
<cfset temp = querySetCell(tags, "tagCount", "75", 2)>
<cfset temp = querySetCell(tags, "tag", "Apollo", 3)>
<cfset temp = querySetCell(tags, "tagCount", "50", 3)>
<cfset temp = querySetCell(tags, "tag", "Flash", 4)>
<cfset temp = querySetCell(tags, "tagCount", "25", 4)>
<cfset temp = querySetCell(tags, "tag", "Photoshop", 5)>
<cfset temp = querySetCell(tags, "tagCount", "5", 5)>
<!--- calculate our hit ranges etc. --->
<cfset tagValueArray = ListToArray(ValueList(tags.tagCount))>
	<cfset max = ArrayMax(tagValueArray)>
	<cfset min = ArrayMin(tagValueArray)>
	<cfset diff = max - min>
	<!--- 
		scaleFactor will affect the degree of difference between the different font sizes.
		if you have one really large category and many smaller categories, then set higher.
		if your category count does not vary too much try a lower number.		 
	--->	<!--- 
		scaleFactor will affect the degree of difference between the different font sizes.
		if you have one really large category and many smaller categories, then set higher.
		if your category count does not vary too much try a lower number.		 
	--->
	<cfset scaleFactor = 25>
	<cfset distribution = diff / scaleFactor>
	
	<!--- optionally add a range of colors in the CSS color property for each class --->
	<cfoutput>
		<style>
			.smallestTag { font-size: 9px; }
			.smallTag { font-size: 11px; }
			.mediumTag { font-size: 13px; }
			.largeTag { font-size: 16px; }
			.largestTag { font-size: 20px; } 
		</style>
		
		
		<cfloop query="tags">
			<cfsilent>
				<cfif tags.tagCount EQ min>
					<cfset class="smallestTag">
				<cfelseif tags.tagCount EQ max>
					<cfset class="largestTag">
				<cfelseif tags.tagCount GT (min + (distribution*2))>
					<cfset class="largeTag">
				<cfelseif tags.tagCount GT (min + distribution)>
					<cfset class="mediumTag">
				<cfelse>
					<cfset class="smallTag">
				</cfif>
			</cfsilent>
			<a href="foo"><span class="#class#">#lcase(tags.tag)#</span></a>
		</cfloop>
	</cfoutput>

This question was written by Jeremy Petersen
It was last updated on November 21, 2006.

Categories

Display and Layout

Comments

comments powered by Disqus