1. ホーム
  2. function

[解決済み] D3キー機能

2022-02-17 03:50:37

質問事項

読者は以下から推測されるように、私はD3にはかなり新しいです...私は現在、以下を使用して実験しています。 .enter().exit().remove() . key関数が何をするのか理解したいのですが...? Chrome >ConsoleでDOMを見ていますが、以下のような明らかな違いは見当たりません。 .data(dataSet, keyFunction) とキー機能なし .data(dataSet) .

どなたか、この謎のキー関数が何をするものなのかを正確に理解するために、何か試してみたい実験(またはコンソール表現)があれば教えてください...。

どのように解決するのですか?

私もd3は初めてで、キー機能で悩んでいました。 トリスタン・リードの回答は、key関数についてあまり語られていないので、勉強になりませんでした。

まず、キーファンクションなし、そしてありの例で作業してみましょう。

これが、javascriptを適用する前の最初のhtmlです。 2つのdivがあり、何のデータも添付されていません。

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

キー関数がない状態でdata()を呼び出す

javascriptを2行ほど追加してみましょう。

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>

データ() の呼び出しは、キーを使って 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 はデータにバインドされますが、それ以外には何も起こりません。

キーが一致しないデータ要素は、すべて enter() . この場合、キー2,3,4にはマッチしません。 そのため、これらのデータ要素は enter() そして、それぞれに新しい div が追加されます。 追加された div は、それぞれのデータ値にバインドされます。

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

javascriptを変更して、今あるものをそのままに、さらに2行ほど追加してみましょう。 同じselectsをdataコール(別の配列)で実行しますが、今回はkey関数を使用します。 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>

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

2つ目の データ() を呼び出すと、マッチングに使われるキーは次のようになります。

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は、以下のような違いはないと言っています。 データ() の呼び出しは、関数がある場合とない場合があります。 それはおそらく、Tristan Reidが示唆するように、バインドされたデータを持たないhtml要素にkey関数が使われているからでしょう。 バインドされたデータがない場合、マッチするキーは存在しないので、すべてのデータ要素が enter() 関数を使用します。

この例を通して、選択範囲、キー、バインドされたデータの関係がよくわかりました。 誰かの役に立つといいのですが。