javascript
グラフを描画するjqPlotがやたら高性能すぎてけしからん件
by kuippa on 5月.06, 2011, under javascript, ツール
最近、地震関係の情報を解析したり、データを集めたりしてこちらで公開しています。
地震の発生と潮の満ち引き、つまり潮位が何か相関関係があるのではないかという仮定にたち、可視化して調べようとしました。そこでなにげなく採用したのがjqPlotです。
結論としてはどうも関係ありそうという考察に至ったのですが、それはさておき、ここでグラフ化するのに使用したjqPlotがすばらしかったのでそのレビューを書いてみようとおもいます。
jQueryのアドオンでもあるjqPlot。ひとことでいうと、ともかく高性能。
3.11以降、日本付近で観測されたM4以上の回数も1500回を軽く超えています。潮位のデータも24時間×90日で2000を越えていることでしょう。5000点以上をプロットしてグラフ化するのに、閲覧にほとんどストレスがないです。(あ、古いマシンで見るとちょっと遅いか。)
まあ、でもこのスクリプトに渡すまでにこなしている処理数を考えるとそれでもかなりすごい。
参考までに、このページのスクリプトがこなしている処理をかいつまんでご案内します。
潮位のデータが気象庁が残念なことにとんでもないオフコンみたいなテキスト固定長データで渡してくれるので、それを日付をキーに配列に格納しています。地震データのカンマ区切りCSVは自分でIRISより作ったものですが、これもテキストからjsで分解して配列に保持しています。
DBにぶっこんでSQLがかければ集計や平均化も楽だったのですが、ここでは配列加工をしないとならなかったので簡易的にループでぐるぐるまわしながらやったりしています。
配列をつくるまでがしんどいのですが、そうこうして作った配列をjqPlotに渡すだけでさっくりグラフになります。
jsonとかCSVとかでデータがきちゃってクライアントサイドでグラフ化しなきゃならないときにすごくいいですね。
[['2011/01/01',10],['2011/01/02',20]]
こんな風に日付をキーにすることもできますし、Y軸を複数対応させたり、それぞれまとめたり、スケールを調整したり、対数対応させたり、ラベルを縦書きにしたり、線の見出しをつけたり、ズームできたりといろいろできます。
その色々をてんこもりにしたのが、上で紹介した図になります。
上のグラフはdata1~4の配列さえつくればこんな設定だけで書けます。
//yticks = [-100,-20,-10,-5, 0, 5, 10, 15, 20, 25, 100]; plot1 = $.jqplot('jqplot', [data1,data2,data3,data4], { legend:{show:true}, cursor: { show:true, tooltipLocation:'sw', zoom:true, clickReset:false, showVerticalLine: true, showHorizontalLine: true }, title:'潮位と地震エネルギーの関係', series:[ {label:'潮位',showMarker:false,lineWidth: 0.3}, {label:'地震M',yaxis:'y2axis',showMarker:false,lineWidth: 0.4}, {label:'地震E',yaxis:'y3axis',showMarker:false,lineWidth: 0.6}, {label:'地震G',yaxis:'y3axis',showMarker:false} ], axesDefaults:{ fill:true, fillToZero: true, showMarker: false, useSeriesColor: true }, axes:{ xaxis:{ renderer:$.jqplot.DateAxisRenderer, label:'日付', // ticks:xticks, labelRenderer: $.jqplot.CanvasAxisLabelRenderer }, yaxis:{ label:'潮位(cm)', min:-20, max:150, // ticks:yticks, tickOptions:{formatString:'%d'}, labelRenderer: $.jqplot.CanvasAxisLabelRenderer }, y2axis:{ label:'地震マグニチュード', autoscale: true, labelRenderer: $.jqplot.CanvasAxisLabelRenderer }, y3axis:{ label:'地震エネルギー', labelRenderer: $.jqplot.CanvasAxisLabelRenderer, renderer:$.jqplot.LogAxisRenderer } } });
きっとこれを見てもらえば勘のいいひとは、すげぇとわかってもらえるはず。jqPlotのページwww.jqplot.com/index.phpにはデモとサンプルwww.jqplot.com/tests/zoomTests.phpのページがあるのですが、円グラフ意外のサンプルで紹介されているような機能をまるっと盛り込んでみました。途中で使うのが楽しくなっちゃって・・・・。
IEとかでブラウジングして回ると、Jsが重すぎてどうしようかというサイトにたどり着くことがよくあるのですが、恐らくそのほとんどはIEでDOMを作る際のオーバーヘッドを考慮されていない&つくる人がIEエンジンを無視しているなどのケースだとおもうのだけど、それでも、今回作成したデータのプロット数をかんがえるとやっぱりjqPlotはとてつもなく優秀だなーと、ソースも殆どみずにつぶやくのでした。
たぶんこれがIE系のブラウザでみると重たいのもループのなかで使いもしないデータを不必要にappendしている箇所のせいだとおもうのです。
閲覧数がおおいサービスで毎度CL側で処理するのはどうかとおもうけど、業務分析とかする閲覧者数がしぼれて即時性が要求されるグラフなどをつくるのおにはとてもいいのではないでしょうか。


