D3.js 面グラフ(area chart)の作成方法
サンプルプログラム
サンプルコード
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>D3 Area Chart</title>
<script src="https://d3js.org/d3.v7.min.js"></script>
</head>
<body>
<script>
// 1. データ準備
var dataset = [
[1, 15],
[5, 25],
[25, 30],
[85, 40],
[100, 42],
[220, 40],
[250, 50],
[330, 95],
[410, 30],
[475, 44],
[480, 50]
];
var width = 400; // グラフ幅
var height = 300; // グラフ高さ
var margin = { "top": 30, "bottom": 60, "right": 30, "left": 60 };
// 2. SVG領域設定
var svg = d3.select("body").append("svg").attr("width", width).attr("height", height);
// 3. 軸スケール(目盛り)設定
var xScale = d3.scaleLinear()
.domain([0, d3.max(dataset, function (d) { return d[0]; })])
.range([margin.left, width - margin.right]);
var yScale = d3.scaleLinear()
.domain([0, d3.max(dataset, function (d) { return d[1]; })])
.range([height - margin.bottom, margin.top]);
// 4. 軸表示
var axisx = d3.axisBottom(xScale).ticks(5);
var axisy = d3.axisLeft(yScale).ticks(5);
svg.append("g")
.attr("transform", "translate(" + 0 + "," + (height - margin.bottom) + ")")
.call(axisx)
.append("text")
.attr("fill", "black")
.attr("x", (width - margin.left - margin.right) / 2 + margin.left)
.attr("y", 35)
.attr("text-anchor", "middle")
.attr("font-size", "10pt")
.attr("font-weight", "bold")
.text("X Label");
svg.append("g")
.attr("transform", "translate(" + margin.left + "," + 0 + ")")
.call(axisy)
.append("text")
.attr("fill", "black")
.attr("text-anchor", "middle")
.attr("x", -(height - margin.top - margin.bottom) / 2 - margin.top)
.attr("y", -35)
.attr("transform", "rotate(-90)")
.attr("font-weight", "bold")
.attr("font-size", "10pt")
.text("Y Label");
// 5. 領域(area)表示
svg.append("path")
.datum(dataset)
.attr("fill", "rgba(70, 130, 180, 0.3)")
.attr("d", d3.area()
.x(function (d) { return xScale(d[0]); })
.y1(function (d) { return yScale(d[1]); })
.y0(yScale(0))
);
svg.append("path")
.datum(dataset)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("d", d3.line()
.x(function (d) { return xScale(d[0]); })
.y(function (d) { return yScale(d[1]); })
);
</script>
</body>
</html>
サンプルコード説明
散布図を対象にグラフを作成する方法のチュートリアルと、折れ線グラフを作成する方法を紹介している。面グラフは折れ線チャートから少し変更するだけで作成できる。
1. データ準備
余白を設定するためにオブジェクトを用意する。
var margin = { "top": 30, "bottom": 60, "right": 30, "left": 60 };
軸を表示するため、下端と左側のマージンを大きく設定する。
2. SVG領域設定
SVGの表示領域を設定する。
3. 軸スケール設定
軸スケールを設定する。
d3.scaleLinear()
上のコードで、domainで設定した範囲をrangeで設定した範囲へ変換する関数を設定する。線グラフの座標を画面のピクセル値へ変換する関数を作成する。
4. 軸表示
D3の関数d3.axisBottom()とd3.axisLeft()を使用して軸要素を設定する。引数を軸スケールの設定で作成した関数にし、callで呼び出すことでSVG要素が自動的に追加される。
var axisx = d3.axisBottom(xScale).ticks(5);
var axisy = d3.axisLeft(yScale).ticks(5);
svg.append("g")
.attr("transform", "translate(" + 0 + "," + (height - margin.bottom) + ")")
.call(axisx)
svg.append("g")
.attr("transform", "translate(" + margin.left + "," + 0 + ")")
.call(axisy)
.ticks()は軸目盛りの数を制御するメソッドである。整数で設定する。
軸を呼び出し、text要素で軸ラベルを追加する。
.append("text")
.attr("fill", "black")
.attr("x", (width - margin.left - margin.right) / 2 + margin.left)
.attr("y", 35)
.attr("text-anchor", "middle")
.attr("font-size", "10pt")
.attr("font-weight", "bold")
.text("X Label");
.append("text")
.attr("fill", "black")
.attr("x", -(height - margin.top - margin.bottom) / 2 - margin.top)
.attr("y", -35)
.attr("transform", "rotate(-90)")
.attr("text-anchor", "middle")
.attr("font-weight", "bold")
.attr("font-size", "10pt")
.text("Y Label");
"text-anchor"はテキストの位置合わせ用の属性で、"middle"で中央揃えを設定している。それぞれ軸に重ならないように35pxずつ移動している。
5. 面領域表示
面グラフを"path"要素で表示する。ここが線グラフと異なる部分である。
svg.append("path")
.datum(dataset)
.attr("fill", "rgba(70, 130, 180, 0.3)")
.attr("d", d3.area()
.x(function(d) { return xScale(d[0]); })
.y1(function(d) { return yScale(d[1]); })
.y0(yScale(0))
);
svg.append("path")
.datum(dataset)
.attr("fill", "none")
.attr("stroke", "steelblue")
.attr("stroke-width", 1.5)
.attr("d", d3.line()
.x(function(d) { return xScale(d[0]); })
.y(function(d) { return yScale(d[1]); })
);
データバインディングは次のようにdatumを使用している。
.datum(dataset)
1つずつデータをバインドするdataとは異なり、"path"にデータセット全体を追加する。また、色の指定時に"rgba(70, 130, 180, 0.3)"を使用している。R、G、B値を0から255で、alpha値(透明度)を0から1で設定する。"opacity"属性でも透明度を設定できるが、"fill"属性と"stroke"属性の透明度を別々に変更したい場合はrgbaを使用する。ここでは"stroke"属性を設定していないため、どちらでもよい。
面領域を描くとき、pathの"d"属性を次のD3メソッドで設定する。
d3.area()
.x(function(d) { return xScale(d[0]); })
.y1(function(d) { return yScale(d[1]); })
.y0(yScale(0))
.x()にx座標を指定する関数を、y0に下側(今回はy=0)のy座標を、y1に上側のy座標を設定する。
2つ目の"path"は折れ線チャートと同じように境界線を設定する。不要な場合は除外する。
d3.line()
.x(function(d) { return xScale(d[0]); })
.y(function(d) { return yScale(d[1]); })
上のコードは境界用"path"の"d"属性を作成する関数である。
まとめ
棒グラフと散布図も同じアルゴリズムで作成できる。参照するとよい。