はじめに
前回は、数式とグラフについて簡単におさらいし、D3を使って図やグラフのグリッドなど基本的な図を書いてみました。今回からは、それらのグリッド上に実際の数式から導き出される値を使ってグラフを記述してみます。
説明では具体的な値を用いていますが、添付のサンプルコードでは係数を変更してグラフを試せるようにしています。ご自身でD3.jsを用いてグラフを作成いただくのが理想ですが、サンプルコードで値を変更するだけでも理解を深めることができるでしょう。
値をプロットして表示する
サンプリングしたデータがどんな状態になっているか見たい場合、もっとも簡単なのは「すべての値をプロットする」方法です。
複数の特徴を含まないデータであれば、プロットするだけでおおよその関係性を把握できるはずです。特に、今回説明する一次関数や二次関数で特徴が示せる場合には、このプロットしたグラフを実際に見ればすぐにイメージが思い浮かぶはずです。
まず、図1のようにランダムな値をプロットしたコードがリスト1です。
// (1) ランダム値を100個作成する let dataset = []; for(let i = 0 ; i < 100; i++){ const _y = (Math.random() * 200); // 0 〜 200 dataset.push({x : i, y:_y}); } const plots = svg.append('g').attr('class','-data'); plots.selectAll("circle") // (2) すべてのcircle要素を選択 .data(dataset) // (3) サンプルデータを指定 .enter().append("circle") // (4) データ数に応じた circle要素を作成 .attr("cx", function(d) { return xScale(d.x); }) // (5) それぞれの中心(X位置) .attr("cy", function(d) { return yScale(d.y); }) // (6) それぞれの中心(Y位置) .attr("r", 3) .attr("class","-plot");

(1)でランダムな値を100個作成します。そして、この100個に相当するcircle要素を作成すれば、各値をプロットとして表現できます。
続いて(2)のselectAll()は指定したセレクタに一致する要素を選択しようと試みます。この(2)~(4)の部分がD3で少々わかりにくいポイントです。
この(2)の処理はこの時点ではまだcircle要素はできていませんが、その後の(3)のdata()、とenter().append()によって要素を作成し、そこで作成した要素が対象になります。
また、data関数はこのあと一次関数グラフなどで説明するdatum関数と似ていますが、data関数は要素自体を繰り返す場合に使います。つまり(4)で指定しているcircle要素を追加する処理をdataで指定した回数だけenterで実行する処理になっています。
このあたりの作法がD3特有ですが、まずはあまり深く考えずに慣れていけばよいでしょう。
そして、(5)(6)でcircle要素の中心を指定しています。中心と言っても、実際には与えられる(x,y)に表示される位置が変わるので、前回説明したスケール関数(数値上の範囲を画面上の範囲に変換する関数)を使って求めます。
このように実行すると、リスト2のようにSVGのcircle要素が100個できあがります。
<circle cx="193.8921953913416" cy="219.28013218776758" r="3" class="-plot"></circle> : (省略) <circle cx="324.89213066843587" cy="160.48050961094174" r="3" class="-plot"></circle>
また、実際には外部データを取り込んで表示したいケースがあります。例えばデータをリスト3の形式でCSVで保持しているとします。
x,y 0,-14 1,25 2,31 3,25 :
最初の行にヘッダがあり、その後はそのヘッダに従いデータが存在するようにします。
そして、先ほどはランダムでデータを作成していた部分をCSVで読みこむように変更するには、リスト4のように変更します。
// (省略) const dataset = []; // (1) CSVデータを指定したURLから読む await d3.csv("/data/sample.csv", (data) => dataset.push(data); }); // (2) 読込結果 console.log(dataset); // [{x:0,y:-14},{x:1,y:25}.....] のような形式
このデータを使ってプロットすると図2の通りになります。

(1)のようにd3.csv関数を使うと簡単に指定したファイル(URL)からデータを読みこめます。読み込み処理は非同期になるため、実際のデータのできあがりを待つにはawaitを使うか、Promiseでのthen関数などを使う必要があります。
読みこんだ結果は(2)のようにヘッダで指定したキー値のJSON配列になります。