RubyでTagCloud (tagcloud-ruby)
Posted by yatsu Sat, 06 Aug 2005 02:22:00 GMT
naoyaのはてなダイアリー – HTML::TagCloud で紹介されているように、PerlにはTagCloud (はてなブックマークの右側に出てくるタグ一覧みたいなやつ) を生成する HTML::TagCloud というものがありますが、Rubyにはそれに相当するものがなさそうだったので、作ってみました。 アルゴリズムはHTML::TagCloudとまったく同じです。
Rubyライセンスということにしておきますので、ご自由にお使いください。
# Author: Masaki Yatsu <yatsu@yatsu.info>
class TagCloud
def initialize
@counts = Hash.new
@urls = Hash.new
end
def add(tag, url, count)
@counts[tag] = count
@urls[tag] = url
end
def css
text = ""
for level in 0..24
font = 12 + level
text << "span.tagcloud#{level} {font-size: #{font}px;}\n"
text << "span.tagcloud#{level} a {text-decoration: none;}\n"
end
text
end
def html(limit = nil)
tags = @counts.sort_by {|a, b| b }.reverse.map {|a, b| a }
tags = tags[0..limit-1] if limit
if tags.empty?
return ""
elsif tags.size == 1
tag = tags[0]
url = @urls[tag]
return %{<span class="tagcloud24"><a href="#{url}">#{tag}</a></span>\n}
end
min = Math.sqrt(@counts[tags.last])
max = Math.sqrt(@counts[tags.first])
factor = 0
# special case all tags having the same count
if max - min == 0
min = min - 24
factor = 1
else
factor = 24 / (max - min)
end
html = ""
tags.sort.each do |tag|
count = @counts[tag]
url = @urls[tag]
level = ((Math.sqrt(count) - min) * factor).to_i
html << %{<span class="tagcloud#{level}"><a href="#{url}">#{tag}</a></span>\n}
end
html
end
def html_and_css(limit = nil)
"<style>\n#{self.css}</style>\n#{self.html(limit)}"
end
end
サンプルは naoyaのはてなダイアリー – HTML::TagCloud をまねて、以下のようにしました。
#!/usr/bin/ruby
require 'tagcloud'
tags = [
{ :tag => 'blog', :count => 20 },
{ :tag => 'ajax', :count => 10 },
{ :tag => 'mysql', :count => 5 },
{ :tag => 'hatena', :count => 12 },
{ :tag => 'bookmark', :count => 30 },
{ :tag => 'rss', :count => 1 },
{ :tag => 'atom', :count => 2 },
{ :tag => 'misc', :count => 10 },
{ :tag => 'javascript', :count => 11 },
{ :tag => 'xml', :count => 6 },
{ :tag => 'perl', :count => 32 },
]
cloud = TagCloud.new
tags.each do |t|
cloud.add(t[:tag], "http://<your.domain>/#{t[:tag]}/", t[:count])
end
print cloud.html_and_css(20)
出力は以下のように、HTML::TagCloudと同じになります。
<style>
span.tagcloud0 {font-size: 12px;}
span.tagcloud0 a {text-decoration: none;}
span.tagcloud1 {font-size: 13px;}
span.tagcloud1 a {text-decoration: none;}
span.tagcloud2 {font-size: 14px;}
span.tagcloud2 a {text-decoration: none;}
span.tagcloud3 {font-size: 15px;}
...
</style>
<span class="tagcloud11"><a href="http://<your.domain>/ajax/">ajax</a></span>
<span class="tagcloud2"><a href="http://<your.domain>/atom/">atom</a></span>
<span class="tagcloud17"><a href="http://<your.domain>/blog/">blog</a></span>
...
さて、こいつを LesserWiki に組み込もうか。
