60

私は最終的に D3 を学習する過程にあり、答えを見つけることができなかった問題に出くわしました。私の質問がライブラリについて慣用的に考えていないためなのか、それとも現在認識していない手順によるものなのかはわかりません。また、私は 6 月に Web 関連のことを始めたばかりなので、javascript についてはかなりの初心者です。

食品のリストとそれぞれの画像をユーザーに提供するツールを作成しているとします。また、別のビューにリンクできるように、各リスト項目に一意の ID でラベルを付ける必要があるという追加の制約を追加しましょう。これを解決するための私の最初の直感は、<div>それぞれ独自の ID を持つ のリストを作成することです。ここで、それぞれdivに独自の<p>とがあり<img>ます。結果の HTML は次のようになります。

<div id="chocolate">
  <p>Chocolate Cookie</p>
  <img src="chocolate.jpg" />
</div>
<div id="sugar">
  <p>Sugar Cookie</p>
  <img src="sugar.jpg" />
</div>

このツールのデータは JSON 配列にあり、個々の JSON は次のようになります。

{ "label": "sugar", "text": "Sugar Cookie", "img": "sugar.jpg" }

HTML を一気に生成する方法はありますか? div を追加する基本ケースから始めると、コードは次のようになります。

d3.select(containerId).selectAll('div')                                                          
   .data(food)
   .enter().append('div')
   .attr('id', function(d) { return d.label; });

<div>では、 aを含む a を追加するとどう<p>なるでしょうか。私の当初の考えは、次のようなことをすることでした:

d3.select(containerId).selectAll('div')                                                          
   .data(food)
   .enter().append('div')
   .attr('id', function(d) { return d.label; })
       .append('p').text('somethingHere');

しかし、これには 2 つの問題があります。(1)div要素からデータを取得する方法と、(2) 1 つの宣言チェーンで複数の子を同じ親に追加するにはどうすればよいですか? に追加する 3 番目のステップを作成する方法が思いつきませんimg

http://bost.ocks.org/mike/nest/を指す別の投稿で、ネストされた選択についての言及を見つけました。しかし、ネストされた選択であり、したがって追加を 3 つのチャンクに分割することは、この状況に適切/慣用的ですか? それとも、宣言の 1 つのチェーンでこの構造を形成する適切に構成された方法が実際にありますか? https://github.com/mbostock/d3/wiki/Selectionsで言及されているサブセレクションを使用する方法があるようですが、その仮説をテストするのに十分な言語に精通していません。

概念レベルから見ると、これら 3 つのオブジェクト ( divp、およびimg) は、個別のエンティティではなく 1 つのグループのように扱われます。コードにもそれが反映されているとよいでしょう。

4

3 に答える 3

85

1 つの連鎖コマンド内に複数の子要素を追加することはできません。親の選択を変数に保存する必要があります。これはあなたが望むことをするはずです:

var data = [{ "label": "chocolate", "text": "Chocolate Cookie", "img": "chocolate.jpg" },
        { "label": "sugar", "text": "Sugar Cookie", "img": "sugar.jpg" }];

var diventer = d3.select("body").selectAll("div")
    .data(data)
  .enter().append("div")
    .attr("id", function(d) { return d.label; });

diventer.append("p")
    .text(function(d) { return d.text; });

diventer.append("img")
    .attr("src", function(d) { return d.img; });​

作業フィドルを参照してください: http://jsfiddle.net/UNjuP/

pまたはのような子要素がimg、その親にバインドされているデータにどのようにアクセスするのか疑問に思っていました。新しい要素を追加すると、データは親から自動的に継承されます。これは、p 要素と img 要素に、親 div と同じデータがバインドされることを意味します。

このデータ伝播は、メソッドに固有のものではありませんappendselection次のメソッドで発生します: appendinsert、およびselect

たとえば、selection.append の場合:

selection.append(名前)

指定された名前の新しい要素を、現在の選択範囲内の各要素の最後の子として追加します。追加された要素を含む新しい選択を返します。新しい各要素は、サブセレクションの選択と同じ方法で、現在の要素のデータを継承します (存在する場合)。名前は定数として指定する必要がありますが、将来的には、既存の要素または関数を追加して名前を動的に生成できるようにする可能性があります。

不明な点があれば、詳細についてお気軽にお尋ねください。


編集

selection.eachメソッドを使用すると、選択内容を変数に格納せずに複数の子要素を追加できます。次に、親からデータに直接アクセスすることもできます。

var data = [{ "label": "chocolate", "text": "Chocolate Cookie", "img": "chocolate.jpg" },
        { "label": "sugar", "text": "Sugar Cookie", "img": "sugar.jpg" }];

d3.select("body").selectAll("div")
    .data(data)
  .enter().append("div")
    .attr("id", function(d) { return d.label; })
    .each(function(d) {
        d3.select(this).append("p")
          .text(d.text);
        d3.select(this).append("img")
          .attr("src", d.img);
    });
于 2012-11-02T23:43:43.537 に答える
26

繰り返しますが、実質的な違いはありませんが、私の好みの方法は「call」を使用することです

var data = [{ "label": "chocolate", "text": "Chocolate Cookie", "img": "chocolate.jpg" },
        { "label": "sugar", "text": "Sugar Cookie", "img": "sugar.jpg" }];

d3.select("body").selectAll("div")
    .data(data)
  .enter().append("div")
    .attr("id", function(d) { return d.label; })
  .call(function(parent){
    parent.append('p').text(function(d){ return d.text; });
    parent.append('img').attr("src", function(d) { return d.img; });​
  });

変数を保存する必要はなく、他の場所で同様の構造を使用する場合は、呼び出された関数を除外できます。

于 2015-04-20T15:12:05.530 に答える