佔位符在輸入選擇中的作用

什麼是輸入選擇?

在 D3.js 中,當一個資料繫結到 DOM 元素時,可能有三種情況:

  1. 元素數量和資料點數量相同;
  2. 元素多於資料點;
  3. 資料點多於元素;

在情況#3 中,沒有相應 DOM 元素的所有資料點都屬於輸入選擇。因此,在 D3.js 中,輸入選擇是在將元素連線到資料之後包含與任何 DOM 元素不匹配的所有資料的選擇。如果我們在輸入選擇中使用 append 函式,D3 將為我們建立繫結該資料的新元素。

這是一個維恩圖,解釋了有關資料點數/ DOM 元素數量的可能情況:

StackOverflow 文件

我們可以看到,輸入選擇是左側的藍色區域:沒有相應 DOM 元素的資料點。

輸入選擇的結構

通常,輸入選擇包含以下 4 個步驟:

  1. selectAll:選擇 DOM 中的元素;
  2. data:計算和解析資料;
  3. enter:將選擇與資料進行比較,建立新元素;
  4. append:在 DOM 中附加實際元素;

這是一個非常基本的例子(看看 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 ):

https://i.stack.imgur.com/NItFz.jpg

請注意,在這種情況下,我們使用 selectAll("div") 作為 enter 選擇變數的第一行。我們有一個包含 6 個值的資料集,D3 為我們建立了 6 個 div。

佔位符的作用

但是假設我們的文件中已經有了 div,就像頂部的 <div>This is my chart</div> 一樣。在那種情況下,當我們寫:

body.selectAll("div")

我們正在選擇現有的 div。因此,我們的輸入選擇將只有 5 個資料而沒有匹配的元素。例如,在這個 jsfiddle 中 ,HTML 中已經存在 div(這是我的圖表),這將是結果:

https://i.stack.imgur.com/5XUmB.jpg

我們不再看到值 40 了:我們的第一個條形消失了,原因是我們的輸入選擇現在只有 5 個元素。

我們在這裡要理解的是,在我們的輸入選擇變數 selectAll("div") 的第一行,這些 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,我們的輸入選擇有 6 個元素,即使我們已經在文件中有一個 div:

https://i.stack.imgur.com/X5ftR.jpg

這裡是相應的 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