d3.js
選択肢
サーチ…
構文
- d3。 選択 (セレクタ)
- d3。 selectAll (セレクタ)
- 選択 。 選択 (セレクタ)
- 選択 。 selectAll (セレクタ)
- 選択 。 フィルタ (フィルタ)
- 選択 。 マージ (その他)
備考
基本的な選択と変更
jQueryとSizzleの構文に精通している場合、d3の選択はそれほど異なるはずはありません。 d3はW3C Selectors APIを模倣して要素とのやりとりを容易にします。
基本的な例として、すべての<p>
を選択し、それぞれに変更を加える:
d3.selectAll('p')
.attr('class','textClass')
.style('color', 'white');
簡単に言えば、これはjQueryで行うことと比較的同じです
$('p')
.attr('class','textClass')
.css('color, 'white')
一般的には、コンテナdivへの単一の選択から始まり、SVG要素を追加します。これは変数(通常はsvgと呼ばれます)に割り当てられます。
var svg = d3.select('#divID').append('svg');
ここから、複数のオブジェクトのサブ選択を行うためにsvg
を呼び出すことができます(まだ存在しない場合でも)。
svg.selectAll('path')
異なるセレクタ
さまざまなセレクタを持つ要素を選択できます。
- byタグ:
"div"
- クラス:
".class"
- by id:
"#id"
- by属性:
"[color=blue]"
- 複数のセレクタ(OR):
"div1, div2, class1"
- 複数のセレクタ(AND):
"div1 div2 class1"
シンプルなデータに基づく選択
var myData = [
{ name: "test1", value: "ok" },
{ name: "test2", value: "nok" }
]
// We have to select elements (here div.samples)
// and assign data. The second parameter of data() is really important,
// it will determine the "key" to identify part of data (datum) attached to an
// element.
var mySelection = d3.select(document.body).selectAll("div.samples") // <- a selection
.data(myData, function(d){ return d.name; }); // <- data binding
// The "update" state is when a datum of data array has already
// an existing element associated.
mySelection.attr("class", "samples update")
// A datum is in the "enter" state when it's not assigned
// to an existing element (based on the key param of data())
// i.e. new elements in data array with a new key (here "name")
mySelection.enter().append("div")
.attr("class", "samples enter")
.text(function(d){ return d.name; });
// The "exit" state is when the bounded datum of an element
// is not in the data array
// i.e. removal of a row (or modifying "name" attribute)
// if we change "test1" to "test3", "test1" bounded
// element will figure in exit() selection
// "test3" bounded element will be created in the enter() selection
mySelection.exit().attr("class", "samples remove");
「入力」選択肢におけるプレースホルダの役割
エンター選択とは何ですか?
D3.jsでは、DOM要素にデータをバインドするとき、次の3つの状況が考えられます。
- 要素の数とデータポイントの数は同じです。
- データポイントよりも多くの要素があります。
- 要素よりも多くのデータ点があります。
状況#3では、対応するDOM要素のないすべてのデータ点が入力選択に属する。したがって、D3.jsでは、 入力選択は、要素をデータに結合した後、DOM要素と一致しないすべてのデータを含む選択項目です。 入力選択でappend
機能を使用すると、D3はそのデータをバインドする新しい要素を作成します。
これは、データ要素の数/ DOM要素の数に関する考えられる状況を説明するベン図である:
わかるように、 入力選択は、左側の青い領域です:対応するDOM要素のないデータポイントです。
エンター選択の構造
通常、 入力選択には次の4つのステップがあります。
-
selectAll
:DOM内の要素を選択します。 -
data
:data
カウントして解析します。 -
enter
。選択をデータと比較して、新しい要素を作成します。 -
append
:DOMに実際の要素をappend
します。
これは非常に基本的な例です( var divs
4つのステップを見てください):
var data = [40, 80, 150, 160, 230, 260];
var body = d3.select("body");
var divs = body.selectAll("div")
.data(data)
.enter()
.append("div");
divs.style("width", function(d) { return d + "px"; })
.attr("class", "divchart")
.text(function(d) { return d; });
そして、これが結果です( ここではjsfiddle )。
この例では、選択入力変数の最初の行にselectAll("div")
を使用しています。 6つの値を持つデータセットがあり、D3は6つのdivを作成しました。
プレースホルダの役割
しかし、私たちのドキュメントにdivがあります。 <div>This is my chart</div>
ようなものです。その場合、私たちが書くとき:
body.selectAll("div")
その存在するdivを選択しています。したがって、入力選択には、要素が一致していないデータが5つしかありません。たとえば、このjsfiddleでは、HTML内にdivが既に存在する場合(これは「これは私のチャートです」)、これが結果になります:
"40"という値はもう見えません。最初の "bar"は消えてしまいました。その理由は、私たちの "enter"選択に今や5つの要素しかないからです。
ここで理解しなければならないのは、入力選択変数selectAll("div")
の最初の行で、それらのselectAll("div")
は単なるプレースホルダです。我々は、すべて選択する必要はありませんdivs
私たちが追加されている場合はdivs
、またはすべてのcircle
我々が追加されている場合はcircle
。私たちは別のものを選ぶことができます。私たちは、「更新」または「終了」を選択することを計画していない場合はそして、私たちは何を選択することができます。
var divs = body.selectAll(".foo")//this class doesn't exist, and never will!
.data(data)
.enter()
.append("div");
このようにして、すべての ".foo"を選択します。ここで、 "foo"は、存在しないだけでなく、コードのどこにも決して作られていないクラスです!しかし、これは重要ではありません。これはプレースホルダだけです。論理はこれです:
"入力"選択であなたが存在しないものを選択した場合、あなたの "入力"選択は常にあなたのすべてのデータを含みます。
今度は.foo
選択すると、ドキュメント内にdivがすでに存在していても、私たちの "入力"選択肢には6つの要素があります:
そして、ここに対応するjsfiddleがあります。
null
選択する
あなたが何も選択していないことを保証する最善の方法は、 null
選択することです。それだけでなく、この方法は他のどの方法よりも速いです。
したがって、入力選択の場合は、次のようにします。
selection.selectAll(null)
.data(data)
.enter()
.append(element);
デモ・フィドルです: https : //jsfiddle.net/gerardofurtado/th6s160p/
結論
「入力」の選択肢を扱うときは、すでに存在するものを選択しないように細心の注意を払ってください。 selectAll
、存在しないものや存在しないもの(「更新」や「終了」の選択をしない場合)を含むものも使用できます。
例のコードは、Mike Bostockの次のコードに基づいています。https : //bl.ocks.org/mbostock/7322386
矢印関数で "this"を使う
D3.jsのほとんどの関数は、引数として無名関数を受け入れます。一般的な例は.attr
、 .style
、 .text
、 .on
、 .data
ですが、リストはそれよりもはるかに大きいです。
そのような場合、選択された要素ごとに無名関数が評価され、順番に渡されます。
- 現在のデータ(
d
) - 現在のインデックス(
i
) - 現在のグループ(
nodes
) -
this
を現在のDOM要素として返します。
データ、インデックス、および現在のグループは、D3.jsの有名な第1引数、第2引数、第3引数(D3 v3.xでは、伝統的にd
、 i
、 p
という名前の引数)として引数として渡されます。ただし、 this
を使用するには、引数を使用する必要はありません。
.on("mouseover", function(){
d3.select(this);
});
上記のコードは、マウスが要素の上にあるときにthis
を選択します。このフィドルで動作することを確認してください: https : //jsfiddle.net/y5fwgopx/
矢印関数
新しいES6構文として、矢印関数は関数式と比較して構文が短くなっています。しかし、 this
常に使用するD3プログラマにとって、落とし穴があります。矢印関数は、 this
コンテキストを独自に作成しません。つまり、矢印の関数では、 this
は囲むコンテキストからの元の意味を持ちます。
これはいくつかの状況で有効ですが、D3でthis
を使用するのに慣れているコーダーにとっては問題です。たとえば、上のフィドルで同じ例を使用すると、これはうまくいかないでしょう:
.on("mouseover", ()=>{
d3.select(this);
});
あなたがそれを疑っているなら、ここでは謎です: https : //jsfiddle.net/tfxLsv9u/
まあ、それは大きな問題ではありません:必要なときには、単純に標準の古い関数式を使うことができます。しかし、矢印関数を使用してすべてのコードを記述したい場合はどうすればよいでしょうか?それは、矢印の機能を持つコードを持っているし、まだ適切に使用することが可能であるthis
D3に?
第2引数と第3引数を組み合わせたもの
答えは「はい 」です。 this
はnodes[i]
と同じです。このヒントは、実際にはD3 API全体に存在します。
...
this
を現在のDOM要素(nodes[i]
)として
説明は簡単です: nodes
はDOMの現在の要素グループで、 i
は各要素のインデックスですnodes[i]
は現在のDOM要素自体を参照しています。つまり、 this
です。
したがって、次のものを使用できます。
.on("mouseover", (d, i, nodes) => {
d3.select(nodes[i]);
});
そして、それに対応する詐欺があります: https : //jsfiddle.net/2p2ux38s/