D3 は、DB の世界でよく知られている JOIN + INSERT/UPDATE/DELETE パターンを実装しています。d3 では、最初にいくつかの DOM 要素を選択してから、それをデータと結合します。
//join existing 'g.class' DOM elements with `data` elements
var join = d3.select('g.class').data(data)
//get the join pairs that did not have 'g.class' join partner and
//INSERT new 'g.class' DOM elements into the "empty slots"
join.enter().append('g').attr('class', 'class')
//get the join pairs that did not have a `data` element as join partner and
//DELETE the existing 'g.class' DOM elements
join.exit().remove()
//get the join pairs that have a `data` element join partner and
//UPDATE the 'g.class' DOM elements
join.attr("name","value")
お分かりのように、UI 要件にうまく適合するデータがあれば、非常に保守しやすいコードを記述できます。このパターン以外のハックを試みると、UI コードはすぐに非常に悲しくなります。UI のニーズに合わせてデータを前処理する必要があります。
D3 は、いくつかのユース ケース用にいくつかのプリプロセッサを提供します。たとえば、ツリーマップレイアウト関数は、階層データ セットを listtreemap.nodes
にフラット化します。これを単純なリストベースのデータ セットとして使用して、各要素の長方形を描画できます。ツリーマップ レイアウトは、すべてのx,y,width,height
値も計算します。四角形を描画するだけで、階層はもう気にしません。
同様に、独自のヘルパー関数を開発して、
- データをより使いやすい形式に変換し、
- UIの「ヒント」でデータを充実させてみる、描画方法
これらの「ヒント」は、ジオメトリ値、ラベル テキスト、色、および基本的に、単一のデータ要素 (ツリーマップ ジオメトリなど) を見て直接導き出すことができず、各要素をいくつか/すべてと関連付ける必要があるすべてのものを含む場合があります。他の要素 (たとえば、ツリー内のノードのネストの深さを決定する)。このようなタスクを 1 つの前処理ステップで実行すると、そのタスクのコードをより簡潔で高速に記述でき、データ処理を UI の描画から分離できます。