blog/content/post/2009-08-10-00001213.md

149 lines
15 KiB
Markdown

---
title: JSONの構造をグラフ化する
author: kazu634
date: 2009-08-10
url: /2009/08/10/_1315/
wordtwit_post_info:
- 'O:8:"stdClass":13:{s:6:"manual";b:0;s:11:"tweet_times";i:1;s:5:"delay";i:0;s:7:"enabled";i:1;s:10:"separation";s:2:"60";s:7:"version";s:3:"3.7";s:14:"tweet_template";b:0;s:6:"status";i:2;s:6:"result";a:0:{}s:13:"tweet_counter";i:2;s:13:"tweet_log_ids";a:1:{i:0;i:4753;}s:9:"hash_tags";a:0:{}s:8:"accounts";a:1:{i:0;s:7:"kazu634";}}'
categories:
- Perl
---
<div class="section">
<p>
はてぶで話題になっていたGraph::Easyを用いてJSONの構造をグラフ化してみました。JSONのデータはiTunesのWebAPIをたたいた結果を用いてみました。
</p>
<h4>
Perlソース
</h4>
<pre class="syntax-highlight">
<span class="synStatement">use strict</span>;
<span class="synStatement">use warnings</span>;
<span class="synStatement">use </span>Perl6::Say;
<span class="synStatement">use </span>WebService::Simple;
<span class="synStatement">use </span>JSON::Syck;
<span class="synStatement">use </span>Data::Dumper;
<span class="synStatement">use utf8</span>;
<span class="synStatement">use </span>Graph::Easy;
<span class="synComment"># === Main Part ===</span>
<span class="synComment"># iTunesのWebAPIをたたくための準備</span>
<span class="synStatement">my</span> <span class="synIdentifier">$itunes</span> = WebService::Simple-&#62;<span class="synStatement">new</span>(
<span class="synConstant">base_url </span>=&#62;
<span class="synConstant">&#34;http://ax.phobos.apple.com.edgesuite.net/WebObjects/MZStoreServices.woa/wa/wsSearch&#34;</span>,
<span class="synConstant">param </span>=&#62; {
<span class="synConstant">country </span>=&#62; <span class="synConstant">'JP'</span>,
<span class="synConstant">lang </span>=&#62; <span class="synConstant">'ja_jp'</span>,
}
);
<span class="synComment"># 「手紙」と「アンジェラ・アキ」で検索</span>
<span class="synStatement">my</span> <span class="synIdentifier">$response</span> = <span class="synIdentifier">$itunes</span>-&#62;get( { <span class="synConstant">term </span>=&#62; <span class="synConstant">&#34;手紙 + アンジェラ・アキ&#34;</span>, } );
<span class="synComment"># 返ってきたJSONを読み込む</span>
<span class="synStatement">my</span> <span class="synIdentifier">$data</span> = JSON::Syck::Load( <span class="synIdentifier">$response</span>-&#62;content );
<span class="synComment"># グラフを作成</span>
<span class="synStatement">my</span> <span class="synIdentifier">$graph</span> = Graph::Easy-&#62;<span class="synStatement">new</span>();
<span class="synComment"># JSONの構造を再帰的に取得する。</span>
<span class="synComment"># recursive_lookは</span>
<span class="synComment"># (1) JSONを格納したリファレンス変数</span>
<span class="synComment"># (2) リファレンス変数をrefした結果</span>
<span class="synComment"># (3) 親のノードを示す文字列</span>
<span class="synComment"># という引数を取る</span>
recursive_look( <span class="synIdentifier">$data</span>, <span class="synStatement">ref</span>(<span class="synIdentifier">$data</span>), <span class="synConstant">&#34;Root&#34;</span> );
<span class="synComment"># グラフの構造をgraphvizで読み込める形式に出力する</span>
<span class="synStatement">print</span> <span class="synIdentifier">$graph</span>-&#62;as_graphviz();
<span class="synStatement">sub</span><span class="synIdentifier"> recursive_look </span>{
<span class="synStatement">my</span> ( <span class="synIdentifier">$ref</span>, <span class="synIdentifier">$type</span>, <span class="synIdentifier">$parent</span> ) = <span class="synIdentifier">@_</span>;
<span class="synComment"># ハッシュだったら</span>
<span class="synStatement">if</span> ( <span class="synIdentifier">$type</span> <span class="synStatement">eq</span> <span class="synConstant">'HASH'</span> ) {
<span class="synStatement">foreach</span> <span class="synStatement">my</span> <span class="synIdentifier">$x</span> ( <span class="synStatement">keys</span> %{<span class="synIdentifier">$ref</span>} ) {
<span class="synIdentifier">$graph</span>-&#62;add_edge_once( <span class="synIdentifier">$parent</span>, <span class="synIdentifier">$x</span> );
recursive_look( <span class="synIdentifier">$ref</span>-&#62;{<span class="synIdentifier">$x</span>}, <span class="synStatement">ref</span>( <span class="synIdentifier">$ref</span>-&#62;{<span class="synIdentifier">$x</span>} ), <span class="synIdentifier">$x</span> );
}
}
<span class="synComment"># 配列だったら</span>
<span class="synStatement">elsif</span> ( <span class="synIdentifier">$type</span> <span class="synStatement">eq</span> <span class="synConstant">'ARRAY'</span> ) {
<span class="synStatement">foreach</span> <span class="synStatement">my</span> <span class="synIdentifier">$x</span> ( @{<span class="synIdentifier">$ref</span>} ) {
<span class="synIdentifier">$graph</span>-&#62;add_edge_once( <span class="synIdentifier">$parent</span>, <span class="synConstant">&#34;Array&#34;</span> );
recursive_look( <span class="synIdentifier">$x</span>, <span class="synStatement">ref</span>(<span class="synIdentifier">$x</span>), <span class="synConstant">&#34;Array&#34;</span> );
}
}
<span class="synStatement">else</span> {
<span class="synComment"># $graph-&#62;add_edge_once( $parent, $ref );</span>
}
}
</pre>
<h4>
実行例
</h4>
<pre class="syntax-highlight">
~/working/tmp_perl on simoom634 <span class="synStatement">[</span><span class="synConstant">542</span><span class="synStatement">]</span> $: perl <span class="synStatement">test</span>.pl <span class="synStatement">&#62;</span> output.dot
~/working/tmp_perl on simoom634 <span class="synStatement">[</span><span class="synConstant">543</span><span class="synStatement">]</span> $: cat output.dot
digraph GRAPH_0 <span class="synSpecial">{</span>
// Generated by Graph::Easy <span class="synConstant"></span>.<span class="synConstant">64</span> at Mon Aug <span class="synConstant">10</span> <span class="synConstant">23</span>:<span class="synConstant">08</span>:<span class="synConstant">26</span> <span class="synConstant">2009</span>
edge <span class="synStatement">[</span> arrowhead<span class="synStatement">=</span><span class="synConstant">open</span> <span class="synStatement">];</span>
graph <span class="synStatement">[</span> rankdir<span class="synStatement">=</span><span class="synConstant">LR</span> <span class="synStatement">];</span>
node <span class="synStatement">[</span>
fontsize<span class="synStatement">=</span><span class="synConstant">11</span>,
fillcolor<span class="synStatement">=</span><span class="synConstant">white</span>,
style<span class="synStatement">=</span><span class="synConstant">filled</span>,
shape<span class="synStatement">=</span><span class="synConstant">box</span> <span class="synStatement">];</span>
Root -<span class="synStatement">&#62;</span> resultCount <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Root -<span class="synStatement">&#62;</span> results <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
results -<span class="synStatement">&#62;</span> Array <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> collectionCensoredName <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> trackCensoredName <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> collectionPrice <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> currency <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> primaryGenreName <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> collectionViewUrl <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> trackNumber <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> discCount <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> previewUrl <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> collectionId <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> trackId <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> artistId <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> trackTimeMillis <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> trackViewUrl <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> trackName <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> wrapperType <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> kind <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> collectionExplicitness <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> trackExplicitness <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> artistName <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> discNumber <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> collectionName <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> artistViewUrl <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> <span class="synStatement">&#34;</span><span class="synConstant">artworkUrl100</span><span class="synStatement">&#34;</span> <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> country <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> trackCount <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> <span class="synStatement">&#34;</span><span class="synConstant">artworkUrl60</span><span class="synStatement">&#34;</span> <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
Array -<span class="synStatement">&#62;</span> trackPrice <span class="synStatement">[</span> color<span class="synStatement">=</span><span class="synConstant">&#34;#000000&#34;</span> <span class="synStatement">]</span>
<span class="synSpecial">}</span>
~/working/tmp_perl on simoom634 <span class="synStatement">[</span><span class="synConstant">544</span><span class="synStatement">]</span> $: dot <span class="synSpecial">-Tgif</span> output.dot <span class="synSpecial">-o</span> foo.png
</pre>
<h4>
出力された画像
</h4>
<p>
<a href="http://flickr.com/photos/7190707@N05/3811677692/" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://flickr.com/photos/7190707@N05/3811677692/', '');" title="graph of iTunes"><img src="http://farm3.static.flickr.com/2456/3811677692_9c2ed961bb_m.jpg" /></a>
</p>
<p>
from <a href="http://flickr.com/people/7190707@N05/" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://flickr.com/people/7190707@N05/', 'typhoon634');">typhoon634</a>
</p>
<h4>
参考
</h4>
<ul>
<li>
<a href="http://d.hatena.ne.jp/acotie/20090731/1249019746" onclick="__gaTracker('send', 'event', 'outbound-article', 'http://d.hatena.ne.jp/acotie/20090731/1249019746', 'Graph::EasyとGraphvizでステキなグラフを作ってみる &#8211; iDeaList::Writing');" target="_blank">Graph::EasyとGraphvizでステキなグラフを作ってみる &#8211; iDeaList::Writing</a>
</li>
</ul>
</div>