web-dev-qa-db-ja.com

D3キー機能

読者が以下から集まるように...私はD3にかなり慣れていません。..現在.enter().exit().remove()を使用して実験しています。主要機能の機能を理解しようとしています...? Chrome> Consoleを使用してDOMを表示しています。.data(dataSet, keyFunction)とキー関数.data(dataSet)がない場合の明らかな違いを確認できません。

誰かが試してみる実験(またはコンソール式)を提案してくれませんか?.

19
markthekoala

私もd3の初心者で、キー機能に苦労していました。トリスタンリードの答えははっきりとはわかりませんでした。重要な機能についてはあまり触れていないからです。

最初にキー機能なしで、次に使用例を見てみましょう。

JavaScriptを適用する前の最初のHTMLは次のとおりです。 2つのdivがあり、何にも添付されているデータはありません。

<body>
    <div>** First div **</div>
    <div>** Second div **</div>
</body>

キー関数なしでdata()を呼び出す

数行のJavaScriptを追加しましょう。

var arr1 = [35, 70, 24, 86, 59];
d3.select("body")
    .selectAll("div")
    .data(arr1)
    .enter()
    .append("div")
    .html(function(d) { return d });

私たちのhtmlは今どのように見えますか?これは、HTMLと関連データ(追加されたコメント)の値です。

<body>
    <div>** First div ** </div>   <!-- data:  35 -->
    <div>** Second div ** </div>  <!-- data:  70 -->
    <div>24</div>                 <!-- data:  24 -->
    <div>86</div>                 <!-- data:  86 -->
    <div>59</div>                 <!-- data:  59 -->
</body>

data()呼び出しは、キーを使用して、divの配列を値の配列と照合しました。配列に使用されるデフォルトのキーはインデックスです。したがって、これらは使用されたキーです。

selected divs (by text)  key       data elements  key
-----------------------  ---       -------------  ---
** First div **          0         35             0
** Second div **         1         70             1
                                   24             2
                                   86             3
                                   59             4

キーについて説明すると、2つのデータ要素は、選択されたdivで一致があります-キー0と1を持つdivです。これらの一致するdivはデータにバインドされますが、他に何も起こりません。

一致するキーのないすべてのデータ要素はenter()に渡されます。この場合、キー2、3、および4は一致しません。これらのデータ要素はenter()に渡され、それぞれに新しいdivが追加されます。追加されたdivもそれぞれのデータ値にバインドされます。

キー関数でdata()を呼び出す

JavaScriptを変更して、現在の内容を維持しながら、数行追加します。データ呼び出し(別の配列)で同じ選択を実行しますが、今回はキー関数を使用します。 arr1とarr2が部分的に重なっていることに注意してください。

var arr1 = [35, 70, 24, 86, 59];
d3.select("body")
    .selectAll("div")
    .data(arr1)                            // no key function
    .enter()
    .append("div")
    .html(function(d) { return d });

var arr2 = [35, 7, 24, 2];
d3.select("body")
    .selectAll("div")
    .data(arr2, function(d) { return d })  // key function used
    .enter()
    .append("div")
    .html(function(d) { return "new: " + d});

結果のhtmlは次のようになります(コメントが追加されています):

<body>
    <div>** First div** </div>    <!-- data:  35 -->
    <div>** Second div ** </div>  <!-- data:  70 -->
    <div>24</div>                 <!-- data:  24 -->
    <div>86</div>                 <!-- data:  86 -->
    <div>59</div>                 <!-- data:  59 -->
    <div>new: 7</div>             <!-- data:  7 -->
    <div>new: 2</div>             <!-- data:  2 -->
</body>

data()への2回目の呼び出しでは、キーの関数によって返された値を使用しました。選択された要素について、関数はdata(への最初の呼び出しによってそれらにすでにバインドされている)データから派生した値を返します。つまり、それらのキーはバインドされたデータに基づいています。

2番目のdata()呼び出しでは、照合に使用されるキーは次のようになります。

selected divs (by text) key       data elements  key
----------------------- ---       -------------  ---
** First div **         35        35             35
** Second div **        70        7              7
24                      24        24             24
86                      86        2              2
59                      59

一致するキーのないデータ要素は7と2です。これらのデータ要素はenter()に渡されます。したがって、本文に2つの新しいdivが追加されます。

では、元の投稿を振り返ってみましょう。 OPは、関数を使用した場合と使用しない場合のdata()呼び出しに違いはないと述べました。これはおそらく、Tristan Reidが示唆するように、バインドされたデータがないHTML要素でキー関数が使用されていたためです。バインドされたデータがない場合、一致するキーがないため、すべてのデータ要素がenter()関数に渡されます。

この例に取り組むことで、選択、キー、バインドされたデータ間の関係を明らかにすることができました。うまくいけば、それは他の誰かに役立つでしょう。

45
broccoli2000

重要な機能は、データを要素に結合する方法を説明しています。指定しない場合のデフォルトのキー関数は、インデックスを使用することです。

これらすべてを理解するために、d3 selectAll/dataがマッチングの2つのフェーズを実行していることを考慮してください。 1つ目はセレクターです。 d3.selectAll('div')、すべてのdivに一致します。 2つ目は、データ結合data([1,2,3])です。これは、渡したデータと一致するデータプロパティを持つ要素を探します。これを理解することは、これを理解することがd3から最大限の利益を得るための基本であると私が思うためです。

これが違いを示す例( フィドルも )です。

_function id (d) { return d; }

d3.select('.no-key').selectAll('div')
    .data([1,2,3])
    .enter().append('div')
    .text(id);

d3.select('.yes-key').selectAll('div')
    .data([1,2,3], id)
    .enter().append('div')
    .text(id);_
_<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<div class='no-key'>
    <div class='a'>already here</div>
</div>
<br/>
<div class='yes-key'>
    <div>already here</div>
</div>_

私は他の答えの努力を称賛しますが、この答えはコンソールを解析する必要はありません、それは機能の実際の違いを示しています。

なぜこの違いが起こるのですか?悲惨な詳細は次のとおりです。

d3.selectAll('div')を実行すると、すべてのdivが選択されます。次に.data([1,2,3])を実行すると、そのデータがこれらのdivに結合されます。ただし、結合にはキー関数がないため、divに[1,2、 3]データ要素として、最初に見つかった3つのdivを使用します。

代わりに.data([1,2,3], function(d){return d;})を実行すると、キー関数はdiv内のデータに対して[1,2,3]を一致させると言うので、データ要素を持つ既存のdivがない限り、既存のdivと一致しませんdiv。

これらすべての説明は.enter().append('div')にあります。もちろん、上記の一致で見つからなかった必要なdivが追加されます。これがすべてのenter().appendビジネスの一番下の行です:(データ要素の数)-(キー関数に一致する既存の要素の数)

お役に立てれば!

12
Tristan Reid

私のSOヒーローからのリクエストごとに、コンソール実験に対する@markthekoalaの要望に明確に対応できるようにしましょうは、.data()演算子内でキー関数を指定する効果を示しています。

http://bl.ocks.org/migurski/4601038

私は実際、これを上記のコメントでリンクした優れた例よりもさらに尖った例と考えています!注:ブロックの長いタイトルは、内部で何が起こっているかについての適切な説明を持っているので、注意深く読んでください。

この [〜#〜] fiddle [〜#〜] でブロックのコードを操作できます。

正直なところ、これら2つの例の説明、特に2番目の例でうまく行われた実験については、説明を改善するのが非常に難しいと思います。

2
FernOfTheAndes