下の続き。
y方向の値の調整
パソコンとかの描画関係のAPIの座標系は左上が0,0なのが一般的です。svgも例にもれず。でも、グラフの座標は左下が0,0だったりしますよね。ということで、y座標のスケールのrangeを逆転させると、いい感じになります。
// yの最小値とyの最大値を500~0の間にスケーリングするryを作成 var ry = d3.scale .linear() .domain([d3.min(datas, a => a.y), d3.max(datas, a => a.y)]) .range([500, 0]); // ここを0, 500だったのを500, 0にする
これでデータの出力が逆になるので、いい感じに左下が小さい値になります。d3.jsのチュートリアルにもある通りですね。
軸の作成
あとは、チュートリアルのここをなぞっていきます。
cssを用意します。TypeScriptのプロジェクトはデフォルトでapp.cssが用意されてるのでそこに足していきます。
本当はsvgの領域内に綺麗に収まるようにデータとか軸の幅とかを調整するのが望ましいんですが、今回は手抜きでsvgを囲むdivタグに余白を設けてお茶を濁してます。これできちんと表示されてるんですがブラウザ依存かもしれません。
.axis path, .axis line { fill: none; stroke: black; shape-rendering: crispEdges; }.axistext{font-family: 'Meiryo UI'; font-size: 11px; }#content{margin: 50px; }
そして、app.tsにチュートリアルの通りのコードを前回のコードに足していきます。
// x軸 var xAxis = d3.svg.axis().scale(rx).orient("bottom"); svg.append("g") // 軸にあてるスタイル用のクラスを設定 .attr("class", "axis") // デフォルトで上に表示されるので下に移動 .attr("transform", "translate(0, 500)") .call(xAxis); // y軸 var yAxis = d3.svg.axis().scale(ry).orient("left"); svg.append("g").attr("class", "axis").call(yAxis);
これで、実行すると以下のような結果に。
いい感じ・・・!あとは、細かい調整とかの範囲でなんとかなりそう。
コード
一応コード全体をのせておきます。
default.htm
<!DOCTYPE html><htmllang="ja"><head><metacharset="utf-8" /><title>TypeScript HTML App</title><linkrel="stylesheet"href="app.css"type="text/css" /><scriptsrc="Scripts/d3.v3.min.js"></script><scriptsrc="app.js"></script></head><body><h1>Graph</h1><divid="content"></div></body></html>
app.css
body{font-family: 'Segoe UI', sans-serif}span{font-style: italic}.axis path, .axis line { fill: none; stroke: black; shape-rendering: crispEdges; }.axistext{font-family: 'Meiryo UI'; font-size: 11px; }#content{margin: 50px; }
app.ts
/// <reference path="Scripts/typings/d3/d3.d.ts" /> window.onload = () => { // 50セットのデータを生成 var datas: Array<{ x: number; y: number }> = []; var seed = d3.random.normal(200, 200); for (var i = 0; i < 50; i++) { datas.push({ x: i * 10, y: seed() }); } // xの最小値とxの最大値を0~500の間にスケーリングするrxを作成 var rx = d3.scale .linear() .domain([d3.min(datas, a => a.x), d3.max(datas, a => a.x)]) .range([0, 500]); // yの最小値とyの最大値を500~0の間にスケーリングするryを作成 var ry = d3.scale .linear() .domain([d3.min(datas, a => a.y), d3.max(datas, a => a.y)]) .range([500, 0]); // id="content"の中に500x500のsvg要素を作成 var svg = d3.select("#content") .append("svg") .attr("width", 500) .attr("height", 500); // pathを組み立ててくれるlineを作成 var line = d3.svg.line() // x座標はrxでスケーリングした結果 .x(d => rx(d.x)) // y座標はryでスケーリングした結果 .y(d => ry(d.y)); // pathを作成して svg.append("path") // データはlineで組み立てて .attr("d", line(datas)) // 塗りつぶしは無しで .attr("fill", "none") // かっこいい青色で線の太さは1 .attr("stroke", "steelblue") .attr("stroke-width", 1); // データの場所に点をうっていく svg.selectAll("circle") .data(datas) .enter() // x座標とy座標はスケーリングした結果で半径は2でかっこいい青色 .append("circle") .attr("cx", d => rx(d.x)) .attr("cy", d => ry(d.y)) .attr("r", 2) .attr("fill", "steelblue"); // x軸 var xAxis = d3.svg.axis().scale(rx).orient("bottom"); svg.append("g") // 軸にあてるスタイル用のクラスを設定 .attr("class", "axis") // デフォルトで上に表示されるので下に移動 .attr("transform", "translate(0, 500)") .call(xAxis); // y軸 var yAxis = d3.svg.axis().scale(ry).orient("left"); svg.append("g").attr("class", "axis").call(yAxis); };