かなりざっくりD3.js入門

#　はじめに
[D3 チュートリアル](http://ja.d3js.info/alignedleft/tutorials/d3/)を参考によりわかりやすく、大雑把にまとめたいと思います。
事前知識は「html,css,javascript,json,xml」とか書いてありますが、やってなくても大丈夫だと思います。
ちなみに、こちらのソースコードは上のチュートリアルをぱぱっと解説しています。

ブラウザはChromeを使います。

##　準備編

####・ダウンロードしてd3.jsを使う場合

まずはD3.jsのファイルをダウンロードします。
ただし、グーグルで検索すると「D3.js - 日本語ドキュメント」が出てきますが、そこではダウンロードしません(出来ません)。
なので本家[D3.js - Data-Driven Documents](http://d3js.org/)からzipファイルをダウンロードします。(今現在はバージョン3.5.9です。)

解凍した時のファイル構成はd3フォルダの中にd3.jsとd3.min.js、LICENSEというファイルが入っています。
今回はd3.jsファイルを使用します。

どこでもいいのでファイルを作ってその中にd3.jsを入れ、index.htmlというhtmlファイルを作ります。
私の場合はD3入門というフォルダを作っています。
<img width="530" alt="スクリーンショット 2015-11-21 20.45.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/57916/799fa346-f154-3bcf-fba7-e96e70bf271b.png">

**これからはindex.htmlファイルに書き込みながらD3.jsを使っていきます。**
index.htmlはこのように書き込んでください。
コメントしてるところにいろいろ書き込みます。

```html:D3入門/index.html
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title>D3 Test</title>
		<script type="text/javascript" src="d3.js"></script>
	</head>
	<body>
		<script type="text/javascript">
			// ここにD3スクリプトを書く
		</script>
	</body>
</html>
```

####・ダウンロードしないでd3.jsを使う場合(ただしネットに繋いでね)

```html:D3入門/index.html
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title>D3 Test</title>
		<script src="http://d3js.org/d3.v3.min.js" charset="utf-8"></script>
	</head>
	<body>
		<script type="text/javascript">
			// ここにD3スクリプトを書く
		</script>
	</body>
</html>
```

どちらでもいいです。

# D3.js入門編
##要素の追加
d3はjQueryみたいに繋げて書くことが出来ます。ただし繋げる順番には注意してください。

```html:D3入門/index.html
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title>D3 Test</title>
		<script type="text/javascript" src="d3.js"></script>
	</head>
	<body>
		<script type="text/javascript">
			d3.select("body").append("p").text("新しいパラグラフ！");
		</script>
	</body>
</html>
```

これを保存してブラウザでindex.htmlを開いてみると(画像は開発ツールも開いています。<img width="1413" alt="スクリーンショット 2015-11-21 20.11.11.png" src="https://qiita-image-store.s3.amazonaws.com/0/57916/74b23f69-3e51-1a08-da25-c29af6f2c11d.png">
)
と表示されています。開発ツールのElementsを確認してみると<p>新しいパラグラフ！</p>とｐタグと中身のテキストが挿入されてますね。

**d3.select("body").append("p").text("新しいパラグラフ！");**の意味は
d3を使いbody要素の**終了タグの手前**にpタグを入れ、pタグの中身のテキストを"新しいパラグラフ！"を入れることです。

ちなみに複数の要素を選択したい場合はselectAll()を使います。

##データと要素を結びつける。
これから先はscriptの中身だけを記述しますのでご了承ください。
まずはソースを見てください。

```html:D3入門/index.html
<script type="text/javascript">
	var dataset = [ 5, 10, 15, 20, 25 ];
			d3.select("body").selectAll("p")
			  .data(dataset)
   			  .enter()
   			  .append("p")
   			  .text("新しいパラグラフ！");
</script>
```
これを実行すると<img width="1222" alt="スクリーンショット 2015-11-21 22.26.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/57916/523b38c8-01ba-99ce-a913-773ae858b13a.png">
こんな風に表示されます。

では解説をします。

**d3.select("body")**はbody要素を見つけ次の処理（つまりその後に続く.selectALL以降）に渡す。

**.selectAll("p")**は、body内のp要素を選択する。**ただし**ここでは該当する要素が存在しないためメソッドは空のセレクションを返します。この空のセレクションは、**すぐ後に作られる(この後の処理で作られる)**パラグラフ要素を表したものだと理解してください。

**.data(dataset)**はデータの値の個数を数え、解析します。データセットには 5 つの値が含まれているので、ここを通過するすべてのメソッドは、それぞれ値ごとに、合計 5 回繰り返されます

**.enter()**データに結びつけた要素（今回はｐタグ）を作成するのに必要。
このメソッドはこのメソッドは最初に DOM を調べ、次に受け渡されたデータを調べます。

もし**該当する DOM 要素の数よりデータの値の個数が多い場合**は、enter() は新規にプレースホルダ（※プレースホルダ：最終的な値が決まるまでの間、仮に確保しておくその値の置き場所）要素を生成し、そのプレースホルダへの参照を次のステップに渡します。

次のステップでは、その参照に対して作業するわけです。

**.append("p")**は enter() が生成したプレースホルダセレクションを受け取り、ここでDOM に p 要素を挿入します。そして生成した要素の参照を次のステップに渡します。

**.text("新しいパラグラフ！")**新しく生成された p 要素の参照を受け取り、テキストを代入。

ほぼコピペですがこんな流れです。

次にブラウザの開発ツールで見てみます。
まずは開発ツールのElementsでpタグが追加されているのを確認してください。

その後はConsole をクリックし以下のコードを入力後リターンキーを押してください。
*console.log(d3.selectAll("p"))*

配列が表示されるので灰色の小さい三角（0: Array[5]）をクリックし詳細を表示します。

0から4までの５つのpが表示される。
初めの0: pの▼をクリック

すると\_\_data__属性にデータの始めの値５が表示されている。

ほかのp要素をみると、\_\_data__ の値が、最初にデータセットで定義した通り、10、15、20、25 となっているはずです。

画像を参照（0: pの場合）。
<img width="1222" alt="スクリーンショット 2015-11-21 22.26.36.png" src="https://qiita-image-store.s3.amazonaws.com/0/57916/c788ee48-c756-6434-a0b2-428db6cd2f47.png">

つまりD3がデータと要素を結びつけるとき、そのデータはDOM（つまりpタグの中に記録されるのではない）中に記録されるのではなく、
**メモリ上でその要素の \_\_data__属性として記録されている。**

##データの使い方
上の例ではdatasetの中身が使われていないので使えるようにします。
最後の行を変更

```html:D3入門/index.html
<script type="text/javascript">
	var dataset = [ 5, 10, 15, 20, 25 ];
			d3.select("body").selectAll("p")
			  .data(dataset)
   			  .enter()
   			  .append("p")
   			  .text(function(d) { return d; });
</script>
```

data()メソッドを使うことで、５回分繰り返し、それぞれの値を無名関数の引数に突っ込まれる。
ただしfunction(d) { return d; }は無名関数で引数ｄを受け取り、ｄを返しています。

<img width="1082" alt="スクリーンショット 2015-11-21 23.28.59.png" src="https://qiita-image-store.s3.amazonaws.com/0/57916/9b48204d-105b-5faf-e22d-aa41182a89ac.png">


text以外にもattr() や　style()も使える。

```html:D3入門/index.html
<script type="text/javascript">
	var dataset = [ 5, 10, 15, 20, 25 ];
			d3.select("body").selectAll("p")
			  .data(dataset)
   			  .enter()
   			  .append("p")
   			  .text(function(d) { return d; })
   			  .style("color", "red");
</script>
```

<img width="1057" alt="スクリーンショット 2015-11-21 23.29.22.png" src="https://qiita-image-store.s3.amazonaws.com/0/57916/d9db78f1-ed4b-5fbf-e7e9-385355e90467.png">


や(インデントがおかしくてすいません。)

```html:D3入門/index.html
<script type="text/javascript">
	var dataset = [ 5, 10, 15, 20, 25 ];
			d3.select("body").selectAll("p")
			  .data(dataset)
   			  .enter()
   			  .append("p")
   			  .text(function(d) { return d; })
   			  .style("color", function(d) {
      			  	if (d > 15) {   // 15より大きい場合
         				return "red";
   			     	} else {
     			      	return "black";
      			  	}
   			  });
</script>
```

<img width="831" alt="スクリーンショット 2015-11-21 23.45.16.png" src="https://qiita-image-store.s3.amazonaws.com/0/57916/295ffecd-5cab-ba43-b058-a91e98146bfd.png">


としたりすることが出来ます。
ここで一区切りです。

##DIV要素の描画
div要素を使って単純な棒グラフを作ります
データセットは
var dataset = [ 5, 10, 15, 20, 25 ];
です。

まずはソースコードを見てください。(今回はindex.htmlの中身すべて表示してます)

```html:D3入門/index.html
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title>D3 Test</title>
		<script type="text/javascript" src="d3.js"></script>
		<style type="text/css">
			div.bar {
         		display: inline-block;
         		width: 20px;
         		height: 75px;  /* この数値は実行時に上書き */
         		background-color: teal;
      		}
   		</style>
	</head>
	<body>
		<script type="text/javascript">
			var dataset = [ 5, 10, 15, 20, 25 ];
			d3.select("body").selectAll("div")
			  .data(dataset)
			  .enter()
			  .append("div")
			  .attr("class", "bar");
		</script>
	</body>
</html>
```

ここで解説。

cssはdiv要素のbarクラスについてスタイルを決めています。

**attr()**メソッドは要素の HTML 属性とその値を設定するために用います。
今回は、div要素にbarクラスを設定しています

ブラウザで開いた時の画像です。
<img width="1287" alt="スクリーンショット 2015-11-22 0.42.32.png" src="https://qiita-image-store.s3.amazonaws.com/0/57916/4ba9d846-77dd-6a46-a416-add0d6c48603.png">
横長の一つの長方形に見える図形は、実はデータセットの各要素に対応した 5 つの縦長の棒が、隙間無く並んだものです。

**スタイルを設定します。**

**style()**メソッドは、CSS のプロパティと値を直接 HTML 要素に設定するために用いられます。

```html:D3入門/index.html
<script type="text/javascript">
var dataset = [ 5, 10, 15, 20, 25 ];
	d3.select("body").selectAll("div")
	  .data(dataset)
	  .enter()
	  .append("div")
	  .attr("class", "bar")
	  .style("height", function(d) {
   	  	  return d + "px";
	  });
</script>
```

ブラウザで表示します。
<img width="1326" alt="スクリーンショット 2015-11-22 0.54.01.png" src="https://qiita-image-store.s3.amazonaws.com/0/57916/06026265-bfbe-f383-ba17-a63556f1317e.png">
見てみるとそれぞれの棒の高さは 5px、10px、15px、20px、25px になってますね。

見栄えが悪いので調整します。
棒の高さをそれぞれ５倍にし、\<style>タグのcssにmargin-right: 2px;を加える事で右側にスペースをつくる

```html:D3入門/index.html
<!DOCTYPE html>
<html lang="ja">
	<head>
		<meta charset="utf-8">
		<title>D3 Test</title>
		<script type="text/javascript" src="d3.js"></script>
		<style type="text/css">
			div.bar {
         		display: inline-block;
         		width: 20px;
         		height: 75px;  /* この数値は実行時に上書き */
         		margin-right: 2px;
         		background-color: teal;
      		}
   		</style>
	</head>
	<body>
		<script type="text/javascript">
			var dataset = [ 5, 10, 15, 20, 25 ];
			d3.select("body").selectAll("div")
			  .data(dataset)
			　.enter()
			　.append("div")
			　.attr("class", "bar")
			　.style("height", function(d) {
   			  	var barHeight = d * 5;  // 高さを5倍にする
   				return barHeight + "px";
			  });
		</script>
	</body>
</html>
```

画像はこちら
<img width="1215" alt="スクリーンショット 2015-11-22 1.12.13.png" src="https://qiita-image-store.s3.amazonaws.com/0/57916/8a52f56d-d6be-16ab-700d-57c50966807e.png">

棒グラフらしくなりました！！(^o^)

##data()の力