D3.jsでリソースモニターみたいなグラフの作成
前回、はてなブログで、D3.jsの動作が確認できたので、
表題のようなリソースモニターみたいなグラフができないかと作成してみました。
作成するグラフ
さっそく目標とするグラフを紹介したいと思います。
データが古いものから左にずれていきますので、リソースモニターっぽく表現しようと思います。
ソースコード
基本的には、D3.jsのサンプルなどを参考にして作成しました。
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> </head> <style> /* 軸のスタイル */ .axis path, .axis line { fill: none; stroke: #000; shape-rendering: auto; /*アンチエイリアス処理*/ } /* Pathのスタイル */ .line { fill: none; stroke: steelblue; stroke-width: 1.5px; } </style> <body> <div id="result"> <script src="http://d3js.org/d3.v3.min.js"></script> <script> // マージンの設定(領域) var margin = {top: 30, right: 20, bottom: 30, left: 50}, width = 400 - margin.left - margin.right, height = 300 - margin.top - margin.bottom; // 描画データ var array = [ 2 , 0 , 3 , 4 , -1 , -2 , 5 , -3 , 1 , -5] ; // スケールの設定 x要素としてインデックス var xScale = d3.scale.linear() .domain(d3.extent(array, function(d,i) { return i; })) .range([0, width]); // スケールの設定 y要素として配列の値 var yScale = d3.scale.linear() .domain(d3.extent(array, function(d,i) { return d; })) .range([height, 0]); // X軸 var xAxis = d3.svg.axis() .scale(xScale) .orient("bottom") .tickFormat(""); // 軸ラベルはなしにした // Y軸 var yAxis = d3.svg.axis() .scale(yScale) .orient("left"); // 線グラフのラインオブジェクト var linestyle = "linear"; var line = d3.svg.line() .x(function(d,i) { return xScale(i); }) .y(function(d,i) { return yScale(d); }) .interpolate(linestyle); // SVGの追加 var svg = d3.select("#result").append("svg") .attr("width", width + margin.left + margin.right) .attr("height", height + margin.top + margin.bottom) .append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); // グループ要素にX軸を追加 svg.append("g") .attr("class", "x axis") .attr("transform", "translate(0," + height / 2 + ")") // 真ん中にした .call(xAxis); // グループ要素にY軸を追加 svg.append("g") .attr("class", "y axis") .call(yAxis) .append("text") .attr("x", 10) .attr("y", -10) .style("text-anchor", "end") .text("Value"); // 実際のラインを追加 var paths = svg.append("path") .datum(array) // 配列をマッピング .attr("class", "line") .attr("d", line); // データ追加し、再描画がするメソッド function pushData(){ // 先頭を削除 array.shift(); // +5から-5までの乱数発生 var rand = Math.floor( Math.random() * 11 ) - 5 ; // 配列に追加 array.push(rand); // path要素を削除 // paths.remove(); // あらたにPath追加 line.interpolate(linestyle); // 追加して削除だったが、Data-Drivenっぽくない // paths = svg.append("path") // .datum(array) // .attr("class", "line") // .attr("d", line); // データだけ入れ替る。動きは一緒。 paths.attr("d", line); } // スタイルを変える(コンボのイベント) function changeStyle(obj){ linestyle = obj.value; } </script> </div> </body> <input type="button" value="Add" onclick="pushData()"/> <select name="interpolate" onChange="changeStyle(this)" > <option value="linear">linear</option> <option value="cardinal">cardinal</option> <option value="step-before">step-before</option> <option value="step-after">step-after</option> </select> </html>
タイマーなどをうまく使うことで、リアルタイムにグラフが更新できるようになりそうです。
これを使ってそれっぽいグラフを次、作成したいと思います。
心電図っぽくして遊ぶのも面白いかもしれませんね。
補足
どうやら、はてなブログ上でうまく動いていなかったようなので、画像に修正しました。
変数名が衝突していたのかな。。
はてなブログ上で、JavaScriptをゴリゴリ動かすより、CodePen利用したほうがいいかもしれませんね。
CodePen - Front End Developer Playground & Code Editor in the Browser
補足2
ソースコードが Data-Drivenっぽくなかったので修正しました。
こちらの記事で動作確認できます。
stone-book.hatenablog.com