15 Sep 2014, 13:56

D3.js、DBからのデータ連携方法の検討

こんにちは。もーすけです。
Web上でのデータのグラフ化にどんな方法をとっていますか?いろいろ検討してD3.jsが非常に良さそうだったので使ってみています。今回、データベースにあるデータを読み込ませる方法についていくつか検討してみました。

例えば以下の状況を考えます。

やりたいこと

「DBに格納されているデータを使って、D3.jsで折れ線グラフを描く」

DBの構造

すごく単純に下記のテーブル構造とします。

カラム名 データ型
date datetime
value int

※また、下記ではSinatra上で行っているが、他の言語でも同じ考え方が可能です。

(1) 簡単なAPIのようなものを利用する

先に結論から書くと、今まで次の(2)(3)のようなやりかたをやっていたのだけれど、 これが一番複雑にならずに良いと思いました。

Sinatra側で/csvにアクセスするとcsvファイルをダウンロードできるようにします。

#Sinatra側
get '/csv' do
    content_type 'application/csv'
    attachment 'download.csv'

    #DBからデータ取得(Activerecord利用)
    @data   = Model.all()

    #出力するCSVデータの変数。csvヘッダーを先につけている。
    @csv = "date,value\n"

    #DBのデータをCSVの形にして格納
    @data.each do |d|
        @csv += d.date.to_s + "," + d.value.to_s + "\n"
    end
    
    #csvtest.erbというビューに出力
    erb :csvtest, :layout => false
end

こうすることでhttp://*****/csvにアクセスするとcsvファイルとしてダウンロードできる状態になります。 条件指定をしてデータをダウンロードできるようにしたい場合はGETでパラメータ指定できるようにすれば良いと思います。
また、今回はcsvにしているがjsonなどの他の形式でも同様のことがいえる。もっと複雑な構造のデータを扱うのであればjsonを利用すべきです。

このエンドポイントを使って、D3.js側で以下のように読み込ませる。 d3.jsのcsvを読み込ませる関数の引数にURLを指定してあげればそれで終了。

d3.csv("/csv", function(error, data) {
    (中略)
}

(2) javascriptコードの中でRuby変数を展開させる

d3.jsのdatasetの中でRuby変数を展開させる。ビューにJavascriptを書いているので、ビューの中で変数展開するのと同じ要領。 しかし、jsコードにRubyコードも交じるのはアンチパターンと言えよう。

var dataset = [
<% @data.each do |d| %>
    {date:<%= d.date%>, value:<%= d.value %>},
<% end %>
];

(3) CSVファイルをおいておく

こちらはリアルタイムな更新でなれけばこれはこれでありかもしれない。 publicのフォルダに予めcsvファイルを設置しておき、以下のようにd3.jsで読み込ませる。

d3.csv("test.csv", function(error, data) {
    (中略)
}
関連する記事はこちら
  • Datadog APMとトレーシングの仕組みについて (2019/11/21)
  • [基礎] ElasticSerachなどの外部コンポーネントがあるときのテスト (2019/05/26)
  • SlideShare APIをGoogleAppsScriptから利用する (2018/12/20)
  • Docker Compose上でのRailsアプリケーションの開発フロー (2018/05/02)
  • PHPでhttpヘッダー、x-forwarded-forを受け取る (2016/07/26)
  • comments powered by Disqus
    このエントリーをはてなブックマークに追加