D3 は広く使用されており、現在では主流のデータ視覚化ツールの 1 つとなっています。誰もが初めて d3.js に触れたとき、最も困難な部分は data()、enter()、および exit() の操作でした。
一定期間接してある程度の理解が得られたので、私の理解について簡単にお話したいと思います。
データ()
まず例を見てみましょう:
<body> <p></p> <p></p> <p></p> </body>
実行コード:
d3.select("body").selectAll("p").data([1, 2, 3])
ここでは、data() を使用して、選択した DOM 要素にデータをバインドします。これにより、要素の幅の設定など、データに対して関連する操作を行うことができます。
表面上は何の変化も見られません。ただし、内部的には、対応する DOM 要素に __data__ 属性を追加します。これは document.getElementsByTagName("p")[0].__data__ を通じて確認できます。
enter() と exit()
これら 2 つの操作は、名前だけから何を行うかを推測するのが難しいため、混乱を招きます。
上記の data() の例では、DOM 要素とデータの数は同じです。しかし、それが異なる場合はどうすればよいでしょうか?
enter() と exit() は、この状況を処理するために使用されます。
enter()
DOM の数がデータの数より少ない場合、または DOM がまったくない場合、通常はプログラムに DOM の作成を支援させたいと考えます。
次の例では、DOM 要素を事前に提供しません:
<body> </body>
まだ実行中:
d3.select("body").selectAll("p").data([1, 2, 3])
上記の例との違いは、上記の例では .style("width", "100px") などの操作を引き続き実行できることです。ただし、DOM 要素を選択していないため、最初にそれを作成する必要があるため、ここではそれを行うことはできません。
enter() は、データをバインドした後に DOM 要素の欠落部分を選択するために使用されます。足りない部分なのでどうやって選べばいいのかと疑問に思うかもしれません。ここで、少し想像力を働かせて、存在しないものを選択したと想像する必要があります。これを「仮想 DOM」または「プレースホルダー」と呼ぶことができます。
enter() は選択を行うだけで、必要な DOM 要素を実際に追加するわけではありません。したがって、通常は enter() の後に append() を使用して実際に DOM 要素を作成します。
これからは、d3.select("body").selectAll("p").data([1, 2, 3]).enter().append("p") を使用して、必要な DOM 要素。
入力の処理方法
十分な要素がない場合、通常のアプローチは、append() を使用して要素を追加することです。以下のコードを見てください:
<body> <p></p> <script> var dataset = [3, 6, 9]; var p = d3.select("body").selectAll("p"); //绑定数据后,分别获取update和enter部分 var update = p.data(dataset); var enter = update.enter(); //update部分的处理方法是直接修改内容 update.text( function(d){ return d; } ); //enter部分的处理方法是添加元素后再修改内容 enter.append("p") .text(function(d){ return d; }); </script> </body>
この例では、body には p 要素が 1 つしかありませんが、データは 3 つあるため、enter 部分には 2 つの余分なデータが含まれています。冗長データを扱うメソッドがappend要素であり、それに相当します。処理後、本文には 3 つの p 要素があり、その内容は次のとおりです:
<p>3</p> <p>6</p> <p>9</p>
通常、サーバーからファイルを読み取った後、データは存在しますが、Web ページには要素がありません。これは D3 の非常に重要な機能です。つまり、空のセットを選択し、enter().append() を使用して要素を挿入できます。現在本文に p 要素がないと仮定して、次のコードを参照してください:
var dataset = [10,20,30,40,50]; var body = d3.select("body"); body.selectAll("p") //选择body中所有p,但由于没有p,所以选择了一个空集 .data(dataset) //绑定dataset数组 .enter() //返回enter部分 .append("p") //添加p元素 .text(function(d){ return d; });
上記のコードでは、selectAll は空のセットを選択し、データをバインドします。選択セットが空であるため、data() によって返される更新部分は空です。次に、enter() と append() を呼び出して、各データに対応する要素 p が含まれるようにします。最後に、p 要素の内容を変更します。つまり、Enter 部分を処理する一般的な方法は、append() を使用して要素を追加することです。
終了()
enter() とは反対に、exit() は、データと比較して余分な DOM 要素を選択するために使用されます。
次の例では、もう 1 つの DOM 要素を提供します:
<body> <p></p> <p></p> <p></p> <p></p> </body>
今回は蛇足なので分かりやすいですが、実際に存在する、つまり最後の
です。
さらにある場合は、.remove() を使用してこれらの要素を削除できます。コードは次のとおりです。
d3.select("body").selectAll("p").data([1, 2, 3]).exit().remove();
終了の処理方法
要素が多すぎて、それらに対応するデータがありません。このような要素の場合、通常のアプローチは、remove() を使用して要素を削除することです。本文に 5 つの p 要素があると仮定して、次のコードを参照してください:
var dataset = [10, 20, 30]; var p = d3.select("body").selectAll("p"); //绑定数据之后,分别获取update部分和exit部分 var update = p.data(dataset); var exit = update.exit(); //update的部分的处理方法是修改内容 update.text( function(d){ return d; } ); //exit部分的处理方法是删除 exit.remove();
このコードではexit部分を削除処理しています。削除後は、Web ページに冗長な p 要素はなくなります。
参考資料