Building “Tag Cloud” in Rails
I am working on the new search engine for Adamantine Arts and wanted to display the top 25 queries. I thought it would be nice to display the searches in the cool tag cloud form where the more popular the search the larger the text.
So quick tutorial on how to build a tag cloud in Rails. Hurray for logarithms lately. They are all over the search code.
Criteria :
- Use percent based fonts to display size
- Sizes should be relative (high search popularity doesn’t make HUGE text)
- Top 25 should be displayed randomly, even though we are sorting by the most popular.
So here goes:
In your controller, get your search:
@popular_searches = Search.find(:all, :limit => 25, :order => 'popularity DESC')
@popular_searches = @popular_searches.sort_by { rand }
The last line shuffles/randomizes the entries even though we sorted by popularity.
Next for the view. The min/max could probably stand to be in the controller, but since it is just for display, I have no qualms putting it in the view.
<% pmin = 100 # Minimum font size pmax = 400 #Maximum font size vmin = 10000000000000 #Super large number to init min vmax = -1000000000000 #Super small number to init max for search in @popular_searches if (search.popularity < vmin) vmin = search.popularity end if (search.popularity > vmax) vmax = search.popularity end end %> <% for search in @popular_searches %> <a href="/search/?q=<%=search.search_str %>" style="font-size:<%= ((pmax - pmin) * (Math.log(search.popularity)) / (Math.log(vmax)) + pmin).to_s %>%" title="Search"><%= search.search_str %></a> <% end %>
So the tag font size is a function of the min popularity, the max popularity, the maximum size, minimum size, and the popularity for the specific tag. This will generate you a nice little tag list.
Sources: Tagging math, randomizing Active Record set
The finished product is in beta on the Adamantine Arts search
If you enjoyed this post, please consider to leave a comment or subscribe to the feed and get future articles delivered to your feed reader.

Nice! Simple yet works flawless and saved me half an hour of trying and testing to get that size right. Thanks a lot.