読者です 読者をやめる 読者になる 読者になる

やってみる

アウトプットすべく己を導くためのブログ。その試行錯誤すらたれ流す。

D3.jsでリストを並び替えてみた

clickイベントで。

前回まで

前回はd3.jsのデータ駆動について調べた。

  • 配列をループなしで処理できる
  • data([...]).enter()でデータのほうがDOMより数が多い時、その超過データのみ返す
  • data([...]).exit()でデータのほうがDOMより数が少ない時、その不足データのみ返す

成果物

GitHubd3.ClickAndSort.201702182244

Playgrounds

See the Pen d3.ClickAndSort.20182244 by ytyaru (@ytyaru) on CodePen.

jsfiddle, jsdo.it

開発環境

要点

再帰

clickイベントによるDOM更新をするために再帰している。

なぜわざわざ再帰などということをするのか。パッと見、わかりにくい。それは要素自体のclickイベントで発火させるから。そして、表示の更新には、要素の新規生成と削除で行っているから。

要素まるごと変更

もし、要素を新規作成せず、1回作成したDOMを使いまわすだけなら、作成と削除のコードは再帰にする必要がない。今回はリストの数もランダム変更するため、DOM要素の削除と再作成で対応している。これ以外の方法でリストをまるごと更新する術を知らない。

たとえば、最初にリストの最大数だけ作成しておいて、今回表示する数だけ表示し、ほかは非表示にすることが考えられる。そうすれば毎回再作成せずに済むかもしれない。

APIの使い方

d3.jsのメソッドチェーンに慣れていない。文脈を整理してみた。

問い 答え
どこに差し込むか 選択したDOM要素 select(), selectAll(), …
対象データは何か 配列データ data()
いつ行うか 指定した条件のとき enter(), exit()
何を差し込むか 指定したDOM要素 append(), insert(), …
差し込む要素のどこをどうするか 指定した部分を指定した値に text(), attr(), …
<body></body>
d3.select("body")      // どこに差し込むか: body要素
.data([1, 2, 3, 4, 5]) // 対象データは何か: 配列[1, 2, 3, 4, 5]
.enter()               // いつ行うか    : まだ作成されていない場合のみ
.append("p")           // 何を差し込むか: p要素
.text(function(d) { return d; }); // 差し込む要素のどこをどうするか: textノードの値にdを設定する

たとえばenter()を抜くと、実行されるたびに毎回appendされることになる。

d3.select("body")      // どこに差し込むか: body要素
.data([1, 2, 3, 4, 5]) // 対象データは何か: 配列[1, 2, 3, 4, 5]
.append("p")           // 何を差し込むか: p要素
.text(function(d) { return d; }); // 差し込む要素のどこをどうするか: textノードの値にdを設定する

append()も抜くと、既存DOM要素の更新をする意味になる。

d3.selectAll("p")      // どこに差し込むか: すべてのp要素
.data([1, 3, 5, 7, 9]) // 対象データは何か: 配列[1, 3, 5, 7, 9]
.text(function(d) { return d; }); // 差し込む要素のどこをどうするか: textノードの値にdを設定する

既存DOMを選択する必要がある。もちろん存在しなければ実行できない。またはp要素の数がデータ配列より少なければ、存在している分しかtext値を更新できない。

そこで、p要素がデータ配列数より少ない時は、p要素を追加appendする。この「p要素がデータ配列数より少ない時」を意味するのがenter()である。「新たなデータが入力(enter)されたとき」という意味かもしれない。

また、p要素ががデータ配列数より多い時は、p要素を削除removeする。この「p要素がデータ配列数より多い時」を意味するのがexit()である。「昔のデータが出て行く(exit)とき」という意味かもしれない。

DOM

DOMや、HTML, SVG, XML, SGMLなど各マークアップ言語について知っておくと理解が深まるかもしれない。とくにDOMは操作方法として概要だけでも知っておくとイメージがつかみやすい。ようするに木構造の文書を扱うための仕様である(だと思う)。こちらのサイトにお世話になった。感謝。

d3.jsの肝

「配列データに従ってDOM要素を追加する」のがd3.jsの要点である。

セレクタなど細かい指示と一緒くたになっているからわかりにくくなる。コードも長く見える。for文で回すよりスッキリして見やすいはずなのに。

所感

グラフやその可視化とは遠いところに来てしまった。カッコイイ見た目を求めるより、ちょっとコーディングが楽になるシンタックスシュガーについて勉強するというくらいの感覚でいると、達成感を得ながら学習できそう。基礎を固めることが最強への近道。