JavaScriptでTreemap
著名なサイト『百式』さんで検索結果をマップ形式で表示する検索サイトの紹介(リストからマップへ)がされていて、
なんか新しいなーって思った。TagCloudと同じで視覚で結果をうったえるってわかりやすくていいよね。
PHP でtreemapの実装をされている方(Treemap PHP Source Code - neurofuzzy)がいて、コードも公開されていたのでアルゴリズムはそのままに(真似してます)JavaScriptで実装してみた。
//■JavaScript //require Prototype.js function render_treemap(nodes) { var divTmp = new Template('<div class="node" style="width:#{width}px;height:#{height}">#{tag}</div>'); return (function(nodes, width, height, depth) { if (nodes.length == 1) { var textsize = Math.floor(width / nodes[0].label.length); textsize = Math.min(textsize, height); return '<a class="textnode" href="#" style=" font-size:'+textsize+'px">'+nodes[0].label+'</a>'; } var tag = ''; if (depth == 0) tag += '<div class="treemap" style="width:'+width+'px; height:'+height+'px;">'; var m = Math.ceil(nodes.length / 2); var a = nodes.slice(0, m); var b = nodes.slice(m, nodes.length); var aper = a.inject(0, function(ret, v) { return ret + v.size }) / nodes.inject(0, function(ret, v) { return ret + v.size }); var bper = 1 - aper; if (depth % 2 == 0) { var awidth = Math.ceil(width * aper); var bwidth = width - awidth; var aheight = height; var bheight = height; } else { var awidth = width; var bwidth = width; var aheight = Math.ceil(height * aper); var bheight = height - aheight; } tag += divTmp.evaluate({tag: arguments.callee.call(null, a, awidth, aheight, depth+1), width: awidth, height: aheight}); tag += divTmp.evaluate({tag: arguments.callee.call(null, b, bwidth, bheight, depth+1), width: bwidth, height: bheight}); if (depth == 0) tag += '</div>'; return tag; }).call(null, nodes, 300, 200, 0); } //■CSS div.treemap { margin-bottom: 4px; font-family: Lucida Grande, Lucida Sans Unicode, Tahoma, Arial, sans serif; } div.treemap div.node { float: left; clear: none; background-color: #CCCC00; } div.treemap a.textnode { display: block; font-size: 10px; text-align: center; width: 100%; height: 100%; display: block; float: left; color: #fff; overflow: hidden; background-color: #A4C088; text-decoration: none; } a.textnode { border: 1px solid black; }
使い方はこんな感じ
var n = [{label:'りんご', size: 20}, {label:'オレンジ', size: 30}, {label:'グレープ', size: 80}, {label:'いちご', size: 15}, {label:'キューイ', size: 40}, {label:'バナナ', size: 5}]; $('panel').innerHTML = render_treemap(n);
まだ、重要度によって色を変えたりだとかが実装されてないんだよね。
TagCloudみたいな感じでclassNameを振っていこうかなと思ってる。
Tags: ajax, javascript