スポンサーリンク

JavaScript で,クリックした座標に点を追加できるグラフチャートを描画する方法 (jQuery のプラグイン jquery.sparklines / jquery.flotの使い方)


JavaScriptを使って,ブラウザ上でグラフチャートを作成する事ができる。

  • 折れ線グラフ
  • 棒グラフ
  • 点だけでプロット

のようにグラフの種類を変えたり,色を付けたり,プロットした点をマウスで操作したりすることもできる。

IEFirefoxの両方に対応。



下記では,サンプルコード付きで描画用ライブラリを2つ紹介する。


試してみるのは,

  1. 簡易なライブラリである sparklines
  2. 多機能な flot

の2つ。

どちらも jQuery のプラグインなので,jQuery も入手して同フォルダに設置しておくこと。

jQueryダウンロード
http://docs.jquery.com/Downloading_jQ...

(1)sparklines で手軽に描画

このライブラリは,プラグインの紹介記事にて「小さなかわいいグラフが簡単に描ける!」として紹介された事がある。

jQuery sparklines ダウンロード
http://www.omnipotent.net/jquery.spar...


JavaScriptで小さくて可愛いグラフを作れる「jQuery Sparklines」
http://phpspot.org/blog/archives/2008...

上記のサイトを見てわかる通り,手軽ながらもバリエーションに富んだグラフが描ける。


jquery.sparkline.jsと同じフォルダに,下記のHTMLをコピペして設置。

<body>


<div id="my_div"></div>


<script src="jquery.js"></script>
<script src="jquery.sparkline.js"></script>
<script language="JavaScript">

window.onload = function()
{
	// 1本目のグラフ
	var arr1 = [1,2,4,10,8];
	$("#my_div").sparkline( arr1, {
		composite:true,
		type:  "line",
		width: "100px",
		height:"100px",
		lineColor:"#0000ff",
		fillColor:""
	});

	// 2本目のグラフ
	var arr2 = [2,4,10,8,1];
	$("#my_div").sparkline( arr2, {
		composite:true,
		type:  "line",
		width: "100px",
		height:"100px",
		lineColor:"#ff0000",
		fillColor:""
	});
}

</script>

</body>

→動作サンプルはこちら


この通り,データとして配列を用意して,sparkline() で渡すだけ。


デザインオプションとしてJSONを渡す。

上記のようにfillColorを空欄にすると,グラフと軸の間が塗りつぶされなくなる。


IEのようなCanvasオブジェクトが使えないブラウザであっても,あっさり描画できてしまうのがすごい。



欠点は,軸や凡例をカスタマイズできないこと。

これでも視覚効果としてサイトのアクセサリにする事はできるが,もしまともに数値を表現したいなら,次項の flot を使うとよい。


(2)多機能な flot でインタラクティブに描画

jQuery.flot は下記ページからダウンロードできる。
http://code.google.com/p/flot/

Featured Downloads のところからzipを選択して,解凍後

  • jquery.flot.js
  • excanvas.js

を同フォルダに置く。



同梱の「API.txt」に詳しいドキュメントが掲載されている。

またWeb上の情報では,下記ページなどが参考になる。

FLOT グラフを描画するPlugin その2
データ抜けを自動で補完する機能を抑制する方法
http://d.hatena.ne.jp/natu_n/20080307...


flot examples
http://people.iola.dk/olau/flot/examp...


では,複数グラフを目盛付きで描画するサンプルから。


ここではインタラクティブな描画の例として,「グラフ上のポイントをクリックすると,どのグラフ上のどのデータをクリックしたのかを認識+出力してくれる」というような機能を持たせてみる。


(<!--[if IE]>の所は半角に直してください)

<body>

<div id="my_div" style="width:600px;height:300px"></div>
<div id="hanrei"></div>

<div id="log"></div>


<script src="jquery.js"></script>
<!--[if IE]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->
<script src="jquery.flot.js"></script>
<script language="JavaScript">

window.onload = function()
{
	// データ準備
	var data1 = [
		[1, 31],
		[2, 41],
		[3, 59],
		[4, 26],
		[5, 53],
		[6, 58],
		[7, 97],
		[8, 93]
	];
	var data2 = [
		[1, 53],
		[2, 58],
		[3, 97],
		[4, 93],
		[5, 31],
		[6, 41],
		[7, 59],
		[8, 26]
	];

	// グラフ描画
	var plot = $.plot(
		$("#my_div"),
		[
			// 表示データ
			{
				label : "My Data 1",
				data  : data1
			},
			{
				label : "My Data 2",
				data  : data2
			},
		],
		{
			lines : { show : true },
			points: { show : true },
			// クリック可能にする
			grid  : { hoverable: true, clickable: true },
			// 凡例
			legend : {
				show      : true,
				noColumns : 2,
				container : $("#hanrei")
			}
		}
	);
	
	// クリック時のイベント設定
	$("#my_div").bind("plotclick", function (event, pos, item) {
		if (item) {
			$("#log").html( item.series.label + " の " + item.dataIndex + " 番目のデータをクリックしました ");
				plot.highlight(item.series, item.datapoint);
		}
	});

}

</script>

</body>

実行画像:



画面下部にクリック時のメッセージが出ている。




次に,「画面上をクリックすると,その座標にデータが追加されて,グラフの一部になる」というコードを書いてみる。


グラフ上の点を,クリックによって動的に追加するわけだ。


(<!--[if IE]>の所は半角に直してください)

<body>

<div id="my_div"></div>
<div id="hanrei"></div>

<div id="log"></div>


<script src="jquery.js"></script>
<!--[if IE]><script language="javascript" type="text/javascript" src="excanvas.js"></script><![endif]-->
<script src="jquery.flot.js"></script>
<script language="JavaScript">

// 同フォルダ上に必要なファイル:
//
// http://code.google.com/p/flot/ から
//   jquery.flot.js
//   excanvas.js
//
// http://docs.jquery.com/Downloading_jQuery#Download_jQuery から
//   jquery.js

window.onload = function()
{

	// データの準備
	var data1 = [
		[1, 31],
		[2, 41],
		[3, 59],
		[4, 26],
		[5, 53],
		[6, 58],
		[7, 97],
		[8, 93]
	];

	// 描画領域をセットアップ
	$("#my_div").css({
		width  : "600px",
		height : "300px"
	});
	// 軸の表示範囲
	var xmin = 1;
	var xmax = 8;
	var ymin = 0;
	var ymax = 100;

	// グラフ描画
	var plot = $.plot(
		$("#my_div"),
		[
			// 表示データ
			{
				label : "My Data 1",
				data  : data1
			}
		],
		{
			lines : { show : true },
			points: { show : true },
			// クリック可能にする
			grid  : { hoverable: true, clickable: true },
			xaxis : { min : xmin, max : xmax },
			yaxis : { min : ymin, max : ymax },
			// 凡例
			legend : {
				show      : true,
				noColumns : 2,
				container : $("#hanrei")
			}
		}
	);
	
	// クリック時のイベント設定
	$("#my_div").bind("click", function (event) {

		// キャンバス中のグリッド領域のサイズ
		var xsize = parseInt( $('#my_div').css("width") )
			 - plot.getPlotOffset().right
			 - plot.getPlotOffset().left;
		var ysize = parseInt( $('#my_div').css("height") )
			 - plot.getPlotOffset().bottom
			 - plot.getPlotOffset().top;

		// キャンバス中のグリッド領域上の位置
		var xpos = event.pageX - $('#my_div').position().left - plot.getPlotOffset().left;
		var ypos = ysize - ( event.pageY - $('#my_div').position().top - plot.getPlotOffset().top );

		// クリックした座標の値
		var xval = xmin + ( xpos / xsize ) * ( xmax - xmin );
		var yval = ymin + ( ypos / ysize ) * ( ymax - ymin );
		$("#log").html( "( " + xval + ", " + yval + " ) の値を追加");
		
		// この座標をグラフに追加して再描画
		data1.push( [ xval, yval ] );
		data1.sort( function( a, b ){
			// b[0] < a[0] ならばスワップする
			return ( b[0] < a[0] )
				? 1
				: -1
				;
		} );       // ←このソート処理を抜かすと滅茶苦茶なつながり方になります。
		plot.draw();
	});

}

</script>

</body>

→動作サンプルはこちら



クリックした場所に,次々に点が追加されていく。そのたびにグラフが新たに折れ曲がる。



(Flashで変形のモーショントゥイーンを設定するときに点をポチポチ追加していく,あの感覚


ちなみに,ソースコード中の sort の部分をコメントアウトすると,グラフの途中に点が挿入されるのではなく,グラフの末尾の点から線が引かれるようになる。


なので,星型などの閉曲線もプロットできるようだ。

いろいろプロットしてみましょう。


補足

上の記事は,下記の質問へのご回答として執筆させて頂きました。

http://q.hatena.ne.jp/1226847021

JavaScriptを使って、グラフアプリを作りたいと考えています。

やりたいことは、2軸のグラフチャートの描画と、グラフチャート上のマウスイベントを拾ってデータを入力を受け付けることです。

最初にまっさらな2軸のチャートがあって、そのチャート上の任意の場所をクリックすると入力フォームが出てきて、入力した場所にポイントが表示されるというイメージです。

そこで、チャート描画のAPIとマウスイベントの拾い方について詳しい方教えてください。

特に後者、マウスイベントをチャート上で拾うサンプルなどあれば、教えてください。