D3.jsを使用して折れ線グラフを作成する方法を学ぶ

D3.jsの機能を使用して、データの美しい表現を描画します。

D3.jsは、最新のブラウザで表示できる美しいデータ表現を作成するために使用されるオープンソースのJavaScriptライブラリです。D3.jsを使用すると、データからさまざまな種類のチャートやグラフを作成できます。

このチュートリアルでは、過去6か月のビットコイン物価指数を表示する折れ線グラフを作成します。外部APIからデータを取得し、DOM内にラベルと軸を含む折れ線グラフをレンダリングします。

また、Scrimbaで無料のD3.jsコースを作成しました。こちらでチェックしてください。

入門

まず、HTML内のCDNからD3.jsライブラリを直接インポートします。

また、HTML内にタグを追加して、D3.jsを使用してその中に折れ線グラフを作成しました。

それでは、JavaScriptコードの記述に移りましょう。まず、DOMが読み込まれたら、外部APIからビットコイン価格指数のデータを読み込みます。

データを取得する

var api = '//api.coindesk.com/v1/bpi/historical/close.json?start=2017-12-31&end=2018-04-01';
document.addEventListener("DOMContentLoaded", function(event) { fetch(api) .then(function(response) { return response.json(); }) .then(function(data) { //DO SOMETHING WITH DATA })});

上記のコードでは、fetchメソッドを使用して外部APIからデータを取得しています。次に、.json()メソッドを使用して解析します。

ここで、このデータをキーと値のペアに変換して、の形式にする必要がありdate:priceます。このために、データを別の関数に送信します。この関数は、データを解析して、目的の形式で返します。

データの解析

.....then(function(data) { var parsedData = parseData(data) })
function parseData(data) { var arr = []; for (var i in data.bpi) { arr.push( { date: new Date(i), //date value: +data.bpi[i] //convert string to number }); } return arr;}

parseDataオブジェクトの別の配列を返す関数にデータを渡します。各オブジェクトには、日付とその特定の日付のビットコインの価格が含まれています。

必要な形式のデータを取得したら、このデータをdrawChart関数に送信します。この関数では、残りのすべてのコードがD3.jsを使用して記述され、折れ線グラフがレンダリングされます。

.....then(function(data) { var parsedData = parseData(data); drawChart(parsedData);})

SVG要素を選択します

このdrawChart関数では、最初にSVG要素を選択し、スタイルを設定します。

function drawChart(data) {
 var svgWidth = 600, svgHeight = 400; var margin = { top: 20, right: 20, bottom: 30, left: 50 }; var width = svgWidth - margin.left - margin.right; var height = svgHeight - margin.top - margin.bottom;
 var svg = d3.select('svg') .attr("width", svgWidth) .attr("height", svgHeight);...

上記のコードでは、最初にselect()メソッドを使用してSVGコンテナーを選択し、次にattr()メソッドを使用して属性を割り当てることにより、SVGコンテナーの幅と高さを設定しています。

また、マージンを定義し、それらの値を使用してSVGコンテナーの幅と高さの属性を計算しています。これらのマージン値は、後でチャートを正しく配置および表示するのに役立ちます。

CSSを使用して、SVGコンテナーに境界線を付けました。

 .line-chart { border: 1px solid lightgray; }

これまでのところ、DOM内にはまだ何もありません。

次に、折れ線グラフ、軸、およびラベルを保持するグループ要素を作成します。

グループ要素の作成と変換

...var g = svg.append("g") .attr("transform", "translate(" + margin.left + "," + margin.top + ")" );

要素をグループ化すると、類似または関連する要素をまとめることができます。ここでは、グループ要素をレンダリングした後、いくつかの変換を提供します。

D3には、要素を変換するためのさまざまなオプションがあります。上記のコードでは、translateプロパティを使用して、グループ要素の左右に余白を付けて再配置しています。

スケールを追加する

次に、チャートにスケールを追加します。

var x = d3.scaleTime().rangeRound([0, width]);
var y = d3.scaleLinear().rangeRound([height, 0]);

ご存知のように、私たちのデータは日付とそれらの日付のビットコインの価値で構成されています。したがって、x軸には日付が含まれ、y軸には値が含まれると想定できます。このようにして、時間に対する折れ線グラフの変化を確認できます。

And so, in the code snippet above, we created a scale of type time on the x-axis and linear type on the y-axis. We are also providing these scales with the ranges as per the width and height of our SVG container.

Create a Line

Let’s now move towards defining our line by using the d3.line method. We will be defining the x and y attributes of the line by passing in anonymous functions and returning the date object and bitcoin value for that particular day.

var line = d3.line() .x(function(d) { return x(d.date)}) .y(function(d) { return y(d.value)}) x.domain(d3.extent(data, function(d) { return d.date })); y.domain(d3.extent(data, function(d) { return d.value }));

Append Axises

We are now going to append our left and bottom axes inside our group element for the line chart. The left axis will represent the value of bitcoin while the bottom axis displays the corresponding date.

g.append("g") .attr("transform", "translate(0," + height + ")") .call(d3.axisBottom(x)) .select(".domain") .remove();

In the above code, we are appending a group element inside our main group and translating it at the very bottom our container. Then, we pass d3.axisBottom method in the call function where d3.axisBottom takes the parameter of x which is defined in the Add Scales section.

g.append("g") .call(d3.axisLeft(y)) .append("text") .attr("fill", "#000") .attr("transform", "rotate(-90)") .attr("y", 6) .attr("dy", "0.71em") .attr("text-anchor", "end") .text("Price ($)");

Similar to the bottom axis, we append another group element and then call on it the d3.axisLeft method which takes the parameter of y. Then, we also style our axis by assigning it different attributes and a label.

If we save and refresh the page, we can see our axes being rendered inside the DOM:

Append a Path

In the last step, we will be appending a path inside our main group element. This path will actually draw the line chart as per the values of the data.

We pass our dataset using the datum method and then set the attributes of fill color, stroke color, and width. In the end, we set the attribute of d which actually gives instruction to the SVG path about where to connect the points of the path.

g.append("path").datum(data).attr("fill", "none").attr("stroke", "steelblue").attr("stroke-linejoin", "round").attr("stroke-linecap", "round").attr("stroke-width", 1.5).attr("d", line);

Here is the final result:

Conclusion

Congratulations! We have successfully created the line chart using D3.js. You can check out the official documentation of D3.js to learn more about different charts and graphs you can create.

If you’re interested in learning more about D3.js, be sure to check out our free course on Scrimba.

I am Sohaib Nehal. I am a Full-Stack Web Application Developer. You can reach me at [email protected] or on Twitter @Sohaib_Nehal. Thank you :-)