サーチ…


構文

  • selection.enter()
  • selection.exit()
  • selection.merge()

データの更新:入力、更新、終了の選択の基本例

静的なデータセットを表示するチャートを作成するのは比較的簡単です。たとえば、データの配列として次のオブジェクトがあるとします。

var data = [
    {title: "A", value: 53},
    {title: "B", value: 12},
    {title: "C", value: 91},
    {title: "D", value: 24},
    {title: "E", value: 59}
];

棒グラフは、それぞれの小節が「タイトル」という名前の小節を表し、その幅が小節の値を表します。このデータセットは変更されないため、棒グラフには「入力」オプションのみがあります。

var bars = svg.selectAll(".bars")
    .data(data);

bars.enter()
    .append("rect")
    .attr("class", "bars")
    .attr("x", xScale(0))
    .attr("y", function(d){ return yScale(d.title)})
    .attr("width", 0)
    .attr("height", yScale.bandwidth())
    .transition()
    .duration(1000)
    .delay(function(d,i){ return i*200})
    .attr("width", function(d){ return xScale(d.value) - margin.left});

ここでは、各バーの幅を0に設定し、遷移後に最終値に設定します。

この入力選択だけで、 このフィドルで見ることができる私たちのチャートを作成するのに十分です。

しかし、私のデータが変わるとどうなりますか?

この場合、グラフを動的に変更する必要があります。これを行う最善の方法は、「入力」、「更新」および「終了」の選択を作成することです。しかし、その前に、コード内でいくつかの変更を行う必要があります。

まず、変化する部分をdraw()という名前の関数の中に移動します:

function draw(){
    //changing parts
};

これらの「変化する部品」には、

  1. 入力、更新、および終了の選択。
  2. 各スケールの領域。
  3. 軸の推移。

そのdraw()関数の中で、データを作成する別の関数を呼び出します。ここでは、5つのオブジェクトの配列を返す関数です。アルファベット順に並べ替えた10文字のうち5文字をランダムに選択し、それぞれ0〜99の値を返します。

function getData(){
    var title = "ABCDEFGHIJ".split("");
    var data = [];
    for(var i = 0; i < 5; i++){
        var index = Math.floor(Math.random()*title.length);
        data.push({title: title[index],
            value: Math.floor(Math.random()*100)});
        title.splice(index,1);
    }
    data = data.sort(function(a,b){ return d3.ascending(a.title,b.title)});
    return data;
};

そして今、私たちの選択に移りましょう。しかしその前には、 オブジェクトの不変性と呼ばれるものを維持するために、selection.dataの第2引数としてキー関数を指定する必要があります。

var bars = svg.selectAll(".bars")
    .data(data, function(d){ return d.title});

それがなければ、私たちの棒はスムーズに移行しませんし、軸の変更に従うのは難しいでしょう(下のフィドルで第2引数を削除することがわかります)。

したがって、 var bars正しく設定した後、選択肢に対処できます。これは出口の選択です:

bars.exit()
    .transition()
    .duration(1000)
    .attr("width", 0)
    .remove();

そして、これは入力と更新の選択です(D3 v4.xでは、更新の選択はmergeを使った入力の選択とmerge ):

bars.enter()//this is the enter selection
    .append("rect")
    .attr("class", "bars")
    .attr("x", xScale(0) + 1)
    .attr("y", function(d){ return yScale(d.title)})
    .attr("width", 0)
    .attr("height", yScale.bandwidth())
    .attr("fill", function(d){ return color(letters.indexOf(d.title)+1)})
    .merge(bars)//and from now on, both the enter and the update selections
    .transition()
    .duration(1000)
    .delay(1000)
    .attr("y", function(d){ return yScale(d.title)})
    .attr("width", function(d){ return xScale(d.value) - margin.left});

最後に、ボタンをクリックするたびにdraw()関数を呼び出します。

d3.select("#myButton").on("click", draw);

そしてこれは、これらの3つの選択肢すべてを実際に示しているフィドルです。

選択のマージ

D3バージョン3の更新パターン

D3を使用してデータビズを適切に変更するには、「入力」、「更新」、および「終了」の選択がどのように機能するかを正しく理解することが重要です。

D3バージョン3以降(実際にはバージョン2以降)、このスニペットは「入力」と「更新」の両方の選択( ここでのライブデモ )の遷移を設定できます

var divs = body.selectAll("div")
    .data(data);//binding the data

divs.enter()//enter selection
    .append("div")
    .style("width", "0px");

divs.transition()
    .duration(1000)
    .style("width", function(d) { return d + "px"; })
    .attr("class", "divchart")
    .text(function(d) { return d; });

移行後にこの結果を与える:

ここに画像の説明を入力

しかし、D3バージョン4を使用すれば、まったく同じコードで何が起こりますか? このライブデモで見ることができます: 何もありません

どうして?

D3バージョン4の更新パターンの変更

コードをチェックしてみましょう。まずはdivsます。この選択は、データを<div>バインドします。

var divs = body.selectAll("div")
    .data(data); 

次に、 divs.enter()があります。これは、不一致の要素を持つすべてのデータを含む選択です。この選択には、最初に関数drawと呼ぶすべてのdivが含まれており、幅をゼロに設定します。

divs.enter()
    .append("div")
    .style("width", "0px");

divs.transition()divs.transition()を持っていますdivs.transition()バージョン3では、 divs.transition()は "enter"セレクションのすべての<div>を最終幅に変更します。しかし、それは意味をなさない! divsは「入力」選択が含まれていないため、DOM要素を変更しないでください。

この奇妙な動作がD3バージョン2と3( ここではソース )で導入され、D3バージョン4で「修正」された理由があります。したがって、上記のライブデモでは何も起こりません。さらに、ボタンをクリックすると、以前の6つのバーが表示されます。これは「更新」の選択項目になっているためです。

「入力」選択を操作する遷移については、別々の変数を作成するか、より簡単な方法で選択項目をマージする必要があります。

divs.enter()//enter selection
    .append("div")
    .style("width", "0px")
    .merge(divs)//from now on, enter + update selections
    .transition().duration(1000).style("width", function(d) { return d + "px"; })
    .attr("class", "divchart")
    .text(function(d) { return d; });

さて、私たちは "入力"と "更新"の選択をマージしました。このライブデモでの動作を確認してください。



Modified text is an extract of the original Stack Overflow Documentation
ライセンスを受けた CC BY-SA 3.0
所属していない Stack Overflow