具体例で学ぶ!情報可視化のテクニック

第6回 はてなブックマークの可視化(後編)

この記事を読むのに必要な時間:およそ 5 分

デモプログラムの作成

それでは,はてなブックマークの人気エントリーを可視化するDemoクラスを見てみましょう。このクラスは,前回のデモプログラムに階層的クラスタリングとツリーマップの実行処理を付け加え,さらに画像ファイルへの出力処理を追加したプログラムとなっています。

少々長くなりますが,以下にコードの全体を掲載します。

リスト6 Demo.java

public class Demo {
    // 出力ファイル名
    private static final String OUTPUT_FILE_NAME =
            "C:/visualization/hatena_bookmark.png";

    public static void main(String[] args) {
        new Demo().run();
    }

    public void run() {
        HatenaBookmarkAPI api = new HatenaBookmarkAPI();
        List<Bookmark> bookmarks = api.getHotEntries();
        System.out.println(bookmarks.size() + " entries.");

        Map<Bookmark, BookmarkDetail> details =
                new HashMap<Bookmark, BookmarkDetail>();
        IndexMapper mapper = new IndexMapper();
        for (Bookmark bookmark : bookmarks) {
            System.out.println(bookmark.title);
            System.out.println("  [url] " + bookmark.url);
            try {
                // サーバの負荷を抑えるため呼び出し間隔を空ける
                Thread.sleep(1000);
            } catch (InterruptedException e) {
            }
            BookmarkDetail detail = api.getDetail(bookmark.url);
            if (detail != null) {
                System.out.println("  [bookmarkCount] " + detail.bookmarkCount);
                System.out.println("  [tags] " + detail.tags);
            }
            // タグを整数インデックスにマッピングする
            for (String tag : detail.tags) {
                mapper.put(tag);
            }
            details.put(bookmark, detail);
        }
        // 階層的クラスタリングの入力データを作成
        List<Item> input = new ArrayList<Item>();
        for (Bookmark bookmark : bookmarks) {
            BookmarkDetail detail = details.get(bookmark);
            input.add(new BookmarkItem(bookmark, detail, mapper));
        }

        // Ward法に基づく階層的クラスタリングを準備
        DistanceEvaluator evaluator = new WardDistanceEvaluator();
        ClusterBuilder builder = new ClusterBuilder(evaluator);

        // クラスタリングを実行
        Node result = builder.build(input);

        // クラスタリング結果をツリーマップに出力
        output(result);
    }

    private void output(Node node) {
        // 出力用画像を作成
        BufferedImage image = new BufferedImage(1024, 768,
                BufferedImage.TYPE_INT_RGB);

        // グラフィックオブジェクトを作成
        Graphics2D g = image.createGraphics();
        g.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
                RenderingHints.VALUE_ANTIALIAS_ON);

        // 背景を白で塗りつぶす
        g.setPaint(Color.WHITE);
        g.fillRect(0, 0, image.getWidth(), image.getHeight());

        // ツリーマップの描画を実行
        TreeMapRenderer renderer = new BinaryTreeMapRenderer();
        Rectangle2D bounds = new Rectangle2D.Double(20, 20,
                image.getWidth() - 40, image.getHeight() - 40);
        renderer.render(g, node, bounds);

        // 画像をPNGファイルに保存
        try {
            ImageIO.write(image, "png", new File(OUTPUT_FILE_NAME));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

著者プロフィール

浜本階生(はまもとかいせい)

1981年生まれ。栃木県出身。東京工業大学情報工学科卒業。技術やアイデアの組み合わせから面白いソフトウェアを生み出したいと日々考えている。現在,ブログの解析および視覚化の試みとして「TopHatenar」「Blogopolis」を開発,運用中。

URLhttp://d.hatena.ne.jp/kaiseh/