選擇容許對文檔對象模型(DOM)進行強大的數據驅動轉換:設置屬性,樣式,屬性,HTML或文本內容等。使用數據鏈接的進入和退出選擇,您還能夠添加或刪除與數據對應的元素。javascript
選擇方法一般返回當前選擇或新選擇,容許經過方法鏈對給定選擇上的多個操做進行簡潔應用。例如,要設置當前文檔中全部段落元素的類和顏色樣式:html
d3.selectAll("p") .attr("class", "graf") .style("color", "red");html5
這至關於:java
var p = d3.selectAll("p"); p.attr("class", "graf"); p.style("color", "red");
按照慣例,返回當前選擇的選擇方法使用四個縮進空間,而返回新選擇的方法僅使用兩個。這有助於經過使它們脫離鏈條來揭示上下文的變化:
d3.select("body") .append("svg") .attr("width", 960) .attr("height", 500) .append("g") .attr("transform", "translate(20,20)") .append("rect") .attr("width", 920) .attr("height", 460);
選擇是不可變的。影響選擇哪些元素(或其順序)的全部選擇方法都返回新選擇而不是修改當前選擇。但請注意,元素必然是可變的,由於選擇驅動文檔的轉換!
若是您使用NPM, npm install d3-selection
。不然,請下載最新版本。您也能夠直接從d3js.org加載,做爲獨立庫或做爲D3 4.0的一部分。支持AMD,CommonJS和vanilla環境。在vanilla中,d3
全球出口:node
<script src="https://d3js.org/d3-selection.v1.min.js"></script> <script> var div = d3.selectAll("div"); </script>
在瀏覽器中嘗試d3選擇。
選擇方法接受W3C選擇器字符串,例如.fancy
選擇具備類花哨的元素,或div
選擇DIV元素。選擇方法有兩種形式:select和selectAll:前者只選擇第一個匹配元素,然後者按文檔順序選擇全部匹配元素。頂級選擇方法d3.select和d3.selectAll查詢整個文檔; 部分選取方法,selection.select和 selection.selectAll,限制選擇到所選擇的元素的後代。git
# d3.selection() <>
選擇根元素。此函數還可用於測試選擇()或擴展選擇原型。例如,要添加檢查複選框的方法:
document.documentElementinstanceof d3.selection
d3.selection.prototype.checked = function(value) { return arguments.length < 1 ? this.property("checked") : this.property("checked", !!value); };
而後使用:
d3.selectAll("input[type=checkbox]").checked(true);
# d3.select(selector) <>
選擇與指定選擇器字符串匹配的第一個元素。若是沒有元素與選擇器匹配,則返回空選擇。若是多個元素與選擇器匹配,則僅選擇第一個匹配元素(按文檔順序)。例如,要選擇第一個錨元素:
var anchor = d3.select("a");
若是選擇器不是字符串,則選擇指定的節點; 若是您已經擁有對節點的引用,例如在事件偵聽器或全局範圍內,則此選項很是有用。例如,要將單擊的段落設置爲紅色:
thisdocument.body
d3.selectAll("p").on("click", function() { d3.select(this).style("color", "red"); });
# d3.selectAll(selector) <>es6
選擇與指定選擇器字符串匹配的全部元素。將按文檔順序(從上到下)選擇元素。若是文檔中沒有元素與選擇器匹配,或者選擇器爲null或未定義,則返回空選擇。例如,要選擇全部段落:github
var paragraph = d3.selectAll("p");
若是選擇器不是字符串,而是選擇指定的節點數組; 若是您已經擁有對節點的引用,例如在事件偵聽器或全局範圍內,那麼這頗有用。節點能夠替代地是諸如a 或的僞陣列。例如,要將全部連接着色爲紅色:
this.childNodesdocument.linksNodeListarguments
d3.selectAll(document.links).style("color", "red");
# selection.select(selector) <>
對於每一個選定的元素,選擇與指定的選擇器字符串匹配的第一個後代元素。若是沒有元素與當前元素的指定選擇器匹配,則當前索引處的元素在返回的選擇中將爲null。(若是選擇器爲null,則返回選擇中的每一個元素都將爲空,從而致使選擇爲空。)若是當前元素具備關聯數據,則此數據將傳播到相應的選定元素。若是多個元素與選擇器匹配,則僅選擇文檔順序中的第一個匹配元素。例如,要選擇每一個段落中的第一個粗體元素:
var b = d3.selectAll("p").select("b");
若是選擇器是一個函數,則按順序計算每一個選定元素,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM元素(節點 [ i ])。它必須返回一個元素,若是沒有匹配元素,則返回null。例如,要選擇每一個段落的上一個兄弟:
var previous = d3.selectAll("p").select(function() { return this.previousElementSibling; });
與選擇 .selectAll不一樣,selection .select不會影響分組:它保留現有的組結構和索引,並將數據(若是有的話)傳播給選定的子組。分組在數據鏈接中起着重要做用。有關此主題的更多信息,請參閱嵌套選擇和如何選擇。
# selection.selectAll(selector) <>
對於每一個選定的元素,選擇與指定的選擇器字符串匹配的後代元素。返回選擇中的元素按此選擇中的相應父節點分組。若是沒有元素與當前元素的指定選擇器匹配,或者選擇器爲null,則當前索引處的組將爲空。所選元素不會今後選擇中繼承數據; 使用selection .data將數據傳播給子節點。例如,要選擇每一個段落中的粗體元素:
var b = d3.selectAll("p").selectAll("b");
若是選擇器是一個函數,則按順序計算每一個選定元素,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM元素(節點 [ i ])。它必須返回一個元素數組(或一個僞數組,如NodeList),若是沒有匹配的元素,則返回空數組。例如,要選擇每一個段落的上一個和下一個兄弟節點:
var sibling = d3.selectAll("p").selectAll(function() { return [ this.previousElementSibling, this.nextElementSibling ]; });
與選擇 .select不一樣,選擇 .selectAll確實會影響分組:每一個選定的後代都按原始選擇中的父元素分組。分組在數據鏈接中起着重要做用。有關此主題的更多信息,請參閱嵌套選擇和如何選擇。
# selection.filter(filter) <>
過濾選擇,返回僅包含指定過濾器爲true 的元素的新選擇。該過濾器能夠或者做爲選擇字符串或函數來指定。若是過濾器是一個函數,則按順序計算每一個選定元素的值,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM元素(節點 [ i ])。
例如,要過濾選擇的錶行以僅包含偶數行:
var even = d3.selectAll("tr").filter(":nth-child(even)");
這大體至關於直接使用d3.selectAll,儘管索引可能不一樣:
var even = d3.selectAll("tr:nth-child(even)");
一樣,使用一個函數:
var even = d3.selectAll("tr").filter(function(d, i) { return i & 1; });
或使用selection.select:
var even = d3.selectAll("tr").select(function(d, i) { return i & 1 ? this : null; })
請注意,:nth-child
僞類是基於一的索引而不是從零開始的索引。並且,上述濾波器功能的含義並不徹底相同:nth-child
; 它們依賴於選擇索引而不是DOM中前面的兄弟元素的數量。npm
返回的篩選選擇會保留此選擇的父項,但與array.filter,同樣,它不會保留索引,由於某些元素可能會被刪除; 若是須要,使用selection .select保留索引。api
返回將此選擇與指定的其餘選擇合併的新選擇。返回的選擇與此選擇具備相同數量的組和相同的父項。此選擇中的任何缺乏(null)元素都將使用指定選擇中的相應元素(若是存在(非空))填充。(若是其餘選擇包含其餘組或父項,則會忽略它們。)
經過selection.join在內部使用此方法來合併綁定數據後的輸入和更新選擇。您也能夠明確合併。例如:
var circle = svg.selectAll("circle").data(data) // UPDATE .style("fill", "blue"); circle.exit().remove(); // EXIT circle = circle.enter().append("circle") // ENTER .style("fill", "green") .merge(circle) // ENTER + UPDATE .style("stroke", "black");
有關更多信息,請參閱selection.data
可是,此方法不用於鏈接任意選擇:若是此選擇和指定的其餘選擇都在同一索引處具備(非空)元素,則在合併中返回此選擇的元素,並忽略其餘選擇的元素。
# d3.matcher(selector) <>
給定指定的選擇器,返回一個函數,若是element 匹配指定的選擇器,則返回true 。此方法在選擇 .filter內部使用。例如,這個:
this
var div = selection.filter("div");
至關於:
var div = selection.filter(d3.matcher("div"));
(雖然D3不是兼容層,但因爲最近element.matches的標準化,此實現確實支持供應商前綴實現。)
# d3.selector(selector) <>
給定指定的選擇器,返回一個函數,該函數返回與指定選擇器匹配的元素的第一個後代。此方法在內部經過selection.select使用。例如,這個:
this
var div = selection.select("div");
至關於:
var div = selection.select(d3.selector("div"));
給定指定的選擇器,返回一個函數,該函數返回this
與指定選擇器匹配的元素的全部後代。此方法在內部經過selection.selectAll使用。例如,這個:
var div = selection.selectAll("div");
至關於:
var div = selection.selectAll(d3.selectorAll("div"));
# d3.window(node) <>
返回指定節點的全部者窗口。若是node是節點,則返回全部者文檔的默認視圖; 若是node是文檔,則返回其默認視圖; 不然返回節點。
# d3.style(node, name) <>
返回具備指定節點的指定名稱的style屬性的值。若是節點具備指定名稱的內聯樣式,則返回其值; 不然,返回計算的屬性值。另請參見selection .style。
修改元素
選擇元素後,使用選擇的轉換方法來影響文檔內容。例如,要設置錨元素的名稱屬性和顏色樣式:
d3.select("a") .attr("name", "fred") .style("color", "red");
要試驗選擇,請訪問d3js.org並打開瀏覽器的開發者控制檯!(在Chrome中,使用⌥⌘J打開控制檯。)選擇元素,而後檢查返回的選擇以查看選擇了哪些元素以及如何對它們進行分組。調用選擇方法並查看頁面內容如何更改。
# selection.attr(name[, value]) <>
若是指定了值,則將具備指定名稱的屬性設置爲所選元素上的指定值,並返回此選擇。若是值是常量,則全部元素都被賦予相同的屬性值; 不然,若是值是一個函數,則按順序計算每一個選定元素的值,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM element(nodes [ i ])。而後使用函數的返回值來設置每一個元素的屬性。空值將刪除指定的屬性。
若是未指定值,則返回選擇中第一個(非null)元素的指定屬性的當前值。僅當您知道選擇包含一個元素時,這一般頗有用。
指定的名稱能夠具備名稱空間前綴,例如在XLink名稱空間中xlink:href
指定href
屬性。見命名空間爲支持的名字空間的地圖; 能夠經過添加到地圖來註冊其餘名稱空間。
# selection.classed(names[, value]) <>
若是指定了值,則經過設置屬性或修改屬性來指定或取消分配所選元素上的指定CSS類名,並返回此選擇。指定的名稱是一個空格分隔的類名稱字符串。例如,要分配類和選定的元素:classclassListfoobar
selection.classed("foo bar", true);
若是該值是真實的,則爲全部元素分配指定的類; 不然,這些類是未分配的。若是值是一個函數,則按順序計算每一個選定元素的值,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM元素(節點 [ i ])。而後,函數的返回值用於爲每一個元素分配或取消分配類。例如,要將類foo隨機地與所選元素的一半相關聯:
selection.classed("foo", function() { return Math.random() > 0.5; });
若是未指定值,則當且僅當第一個(非null)所選元素具備指定的類時,才返回true 。僅當您知道選擇包含一個元素時,這一般頗有用。
# selection.style(name[, value[, priority]]) <>
若是指定了值,則將具備指定名稱的style屬性設置爲所選元素上的指定值,並返回此選擇。若是值是常量,則全部元素都被賦予相同的樣式屬性值; 不然,若是值是一個函數,則按順序計算每一個選定元素的值,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM元素(節點 [ i])。而後使用函數的返回值來設置每一個元素的樣式屬性。null值將刪除style屬性。還能夠指定可選優先級,能夠是null或字符串important
(不帶感嘆號)。
若是未指定值,則返回選擇中第一個(非null)元素的指定樣式屬性的當前值。當前值定義爲元素的內聯值(若是存在),不然定義爲其計算值。僅當您知道選擇包含一個元素時,才能訪問當前樣式值。
警告:與許多SVG屬性不一樣,CSS樣式一般具備關聯的單元。例如,3px
是有效的筆畫寬度屬性值,而3
不是。有些瀏覽器隱式地將px
(像素)單元分配給數值,但並不是全部瀏覽器都這樣作:例如,IE會拋出「無效參數」錯誤!
# selection.property(name[, value]) <>
某些HTML元素具備使用屬性或樣式沒法尋址的特殊屬性,例如表單字段的文本value
和複選框的checked
布爾值。使用此方法獲取或設置這些屬性。
若是指定了值,則將具備指定名稱的屬性設置爲所選元素上的指定值。若是該值是常量,則全部元素都被賦予相同的屬性值; 不然,若是值是一個函數,則按順序計算每一個選定元素的值,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM element(nodes [ i ])。而後使用函數的返回值來設置每一個元素的屬性。空值將刪除指定的屬性。
若是未指定值,則返回選擇中第一個(非null)元素的指定屬性的值。僅當您知道選擇包含一個元素時,這一般頗有用。
# selection.text([value]) <>
若是指定了值,則將文本內容設置爲全部選定元素上的指定值,替換任何現有子元素。若是值是常量,則全部元素都被賦予相同的文本內容; 不然,若是值是一個函數,則按順序計算每一個選定元素的值,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM element(nodes [ i ])。而後使用函數的返回值來設置每一個元素的文本內容。空值將清除內容。
若是未指定值,則返回選擇中第一個(非null)元素的文本內容。僅當您知道選擇包含一個元素時,這一般頗有用。
# selection.html([value]) <>
若是指定了值,則將內部HTML設置爲全部選定元素上的指定值,替換任何現有子元素。若是值是常量,那麼全部元素都被賦予相同的內部HTML; 不然,若是值是一個函數,則按順序計算每一個選定元素的值,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM element(nodes [ i ])。而後使用函數的返回值來設置每一個元素的內部HTML。空值將清除內容。
若是未指定值,則返回選擇中第一個(非null)元素的內部HTML。僅當您知道選擇包含一個元素時,這一般頗有用。
使用selection.append或selection.insert來建立數據驅動的內容; 此方法適用於須要一點HTML的狀況,例如豐富的格式。此外,僅在HTML元素上支持選擇 .html。SVG元素和其餘非HTML元素不支持innerHTML屬性,所以與選擇 .html 不兼容。考慮使用XMLSerializer將DOM子樹轉換爲文本。另請參閱innersvg polyfill,它提供了一個shim來支持SVG元素的innerHTML屬性。
# selection.append(type) <>
若是指定的類型是字符串,則將此類型的新元素(標記名稱)做爲每一個所選元素的最後一個子元素添加,或者在更新選擇中的下一個兄弟元素以前添加(若是這是輸入選擇)。輸入選擇的後一種行爲容許您按照與新綁定數據一致的順序將元素插入DOM; 但請注意,若是更新元素更改順序(即,若是新數據的順序與舊數據不一致),則仍可能須要選擇 .order。
若是指定的類型是一個函數,則按順序爲每一個選定元素計算它,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM元素(nodes [ i ])。此函數應返回要追加的元素。(該函數一般會建立一個新元素,但它可能會返回一個現有元素。)例如,要將DIV元素附加到每一個段落:
d3.selectAll("p").append("div");
這至關於:
d3.selectAll("p").append(function() { return document.createElement("div"); });
這至關於:
d3.selectAll("p").select(function() { return this.appendChild(document.createElement("div")); });
在這兩種狀況下,此方法都返回包含附加元素的新選擇。每一個新元素都以與selection .select相同的方式繼承當前元素的數據(若是有)。
指定的名稱能夠具備名稱空間前綴,例如在SVG名稱空間中svg:text
指定text
屬性。見命名空間爲支持的名字空間的地圖; 能夠經過添加到地圖來註冊其餘名稱空間。若是未指定名稱空間,則名稱空間將從父元素繼承; 或者,若是名稱是已知前綴之一,則將使用相應的命名空間(例如,svg
暗示svg:svg
)。
# selection.insert(type[, before]) <>
若是指定的類型是字符串,則在匹配指定的before選擇器的第一個元素以前,爲每一個選定元素插入此類型的新元素(標記名稱)。例如,before選擇器:first-child
將在第一個子節點以前添加節點。若是未指定before,則默認爲null。(要按照與綁定數據一致的順序追加元素,請使用selection .append。)
兩個類型和以前能夠替代地指定爲其中爲每一個選擇的元件進行評價,爲了功能,正在傳遞的當前數據(d),當前指數(我),和當前組(節點),與此做爲當前DOM元素(nodes [ i ])。的類型函數應該返回要插入的元件; 在以前函數返回的元素應該被插入以後的子元素。例如,要將DIV元素附加到每一個段落
d3.selectAll("p").insert("div");
這至關於:
d3.selectAll("p").insert(function() { return document.createElement("div"); });
這至關於:
d3.selectAll("p").select(function() { return this.insertBefore(document.createElement("div"), null); });
在這兩種狀況下,此方法都返回包含附加元素的新選擇。每一個新元素都以與selection .select相同的方式繼承當前元素的數據(若是有)。
指定的名稱能夠具備名稱空間前綴,例如在SVG名稱空間中svg:text
指定text
屬性。見命名空間爲支持的名字空間的地圖; 能夠經過添加到地圖來註冊其餘名稱空間。若是未指定名稱空間,則名稱空間將從父元素繼承; 或者,若是名稱是已知前綴之一,則將使用相應的命名空間(例如,svg
暗示svg:svg
)。
# selection.remove() <>
從文檔中刪除選定的元素。返回此選擇(已刪除的元素),這些選擇如今與DOM分離。目前沒有專門的API將已刪除的元素添加回文檔; 可是,您能夠將函數傳遞給selection.append或selection.insert以從新添加元素。
# selection.clone([deep]) <>
在所選元素後面緊跟插入所選元素的克隆,並返回新添加克隆的選擇。若是深度是真實的,那麼所選元素的後代節點也將被克隆。不然,只會克隆元素自己。至關於:
selection.select(function() { return this.parentNode.insertBefore(this.cloneNode(deep), this.nextSibling); });
# selection.sort(compare) <>
返回一個新選擇,其中包含根據compare函數排序的此選擇中每一個組的副本。排序後,從新插入元件,以(每所得順序相匹配selection.order)。
比較函數默認爲升序,傳遞兩個元素的數據a和b進行比較。它應返回負值,正值或零值。若是是否認的,那麼a應該在b以前; 若是是確定的,那麼a應該在b以後; 不然,a和b被認爲是相等的,而且順序是任意的。
請注意,排序不保證穩定; 可是,它保證與您的瀏覽器在數組上的內置排序方法具備相同的行爲。
# selection.order() <>
將元素從新插入到文檔中,以使每一個組的文檔順序與選擇順序匹配。這至關於調用 selection.sort若是數據已經排序,但速度要快得多。
# selection.raise() <>
按順序從新插入每一個選定元素做爲其父元素的最後一個子元素。至關於:
selection.each(function() { this.parentNode.appendChild(this); });
# selection.lower() <>
按順序從新插入每一個選定元素做爲其父元素的第一個子元素。至關於:
selection.each(function() { this.parentNode.insertBefore(this, this.parentNode.firstChild); });
# d3.create(name) <>
給定指定的元素名稱,返回包含當前文檔中給定名稱的分離元素的單元素選擇。
# d3.creator(name) <>
給定指定的元素名稱,返回一個建立給定名稱元素的函數,假設它是父元素。經過選擇selection.append和選擇selection.insert在內部使用此方法來建立新元素。例如,這個:
this
selection.append("div");
至關於:
selection.append(d3.creator("div"));
有關支持的名稱空間前綴的詳細信息,請參閱名稱空間,例如SVG元素。
加入數據
有關D3數據鏈接的介紹,請參閱Thinking with Joins。另請參閱常規更新模式示例。
# selection.data([data[, key]]) <>
使用所選元素綁定指定的數據數組,返回表示更新選擇的新選擇:成功綁定到數據的元素。還定義了返回選擇的輸入和退出選擇,可用於添加或刪除與新數據對應的元素。指定的數據是任意值的數組(例如,數字或對象),或返回每一個組的值數組的函數。將數據分配給元素時,它將存儲在屬性中__data__
,從而使數據「粘滯」並在從新選擇時可用。
該數據被指定爲每一個組中選擇。若是選擇有多個組(例如d3.selectAll後跟selection.selectAll),則一般應將數據指定爲函數。將按順序爲每一個組評估此函數,傳遞組的父數據(d,多是未定義的),組索引(i)和選擇的父節點(節點),並將其做爲組的父元素。
結合selection.join(或更明確地selection.enter, selection.exit, selection.append 和selection.remove),選擇 .data可用於輸入,更新和退出元素以匹配數據。例如,要從數字矩陣建立HTML表:
var matrix = [ [11975, 5871, 8916, 2868], [ 1951, 10048, 2060, 6171], [ 8010, 16145, 8090, 8045], [ 1013, 990, 940, 6907] ]; var tr = d3.select("body") .append("table") .selectAll("tr") .data(matrix) .join("tr"); var td = tr.selectAll("td") .data(function(d) { return d; }) .join("td") .text(function(d) { return d; });
在此示例中,數據函數是標識函數:對於每一個錶行,它返回數據矩陣中的相應行。
若是一個鍵未指定功能,則在第一數據的數據被分配給第一選擇的元素,第二數據至該第二選擇的元素,依此類推。甲關鍵功能能夠被指定爲控制哪些數據被分配給哪一個元素,替換默認加入逐索引,經過計算每一個數據和元件的串標識符。爲每一個選定的元素評估此關鍵函數,按順序傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM元素(節點 [ i]]); 返回的字符串是元素的鍵。鍵功能,而後還評價了在每個新的基準數據,正在傳遞的當前數據(d),當前指數(我),以及該組的新數據,與此做爲組的父DOM元素; 返回的字符串是數據的鍵。給定鍵的數據被分配給具備匹配鍵的元素。若是多個元素具備相同的鍵,則將重複的元素放入出口選擇中; 若是多個數據具備相同的密鑰,則將重複數據放入輸入選擇中。
例如,鑑於此文件:
<div id="Ford"></div> <div id="Jarrah"></div> <div id="Kwon"></div> <div id="Locke"></div> <div id="Reyes"></div> <div id="Shephard"></div>
您能夠按鍵加入數據,以下所示:
var data = [ {name: "Locke", number: 4}, {name: "Reyes", number: 8}, {name: "Ford", number: 15}, {name: "Jarrah", number: 16}, {name: "Shephard", number: 23}, {name: "Kwon", number: 42} ]; d3.selectAll("div") .data(data, function(d) { return d ? d.name : this.id; }) .text(function(d) { return d.number; });
此示例鍵函數使用數據d(若是存在),不然返回到元素的id屬性。因爲這些元素先前未綁定到數據,所以在對所選元素計算關鍵函數時,數據d爲空,而在對新數據計算關鍵函數時,數據爲非空。
該更新和輸入選擇在數據順序返回,而退出選擇保留以前加入選擇順序。若是指定了鍵功能,則選擇中元素的順序可能與文檔中的順序不匹配; 根據須要使用selection .order或selection .sort。有關鍵函數如何影響鏈接的更多信息,請參閱條形圖,第2部分和對象常量。
若是未指定數據,則此方法返回所選元素的數據數組。
此方法不能用於清除綁定數據; 使用selection.datum代替。
# selection.join(enter[, update][, exit]) <>
根據須要追加,刪除和從新排序元素,以匹配先前由
selection.data綁定的數據,返回合併的輸入和更新選擇。此方法是更明確selection.enter,selection.exit,selection.append和selection.remove)的替代方法。例如:
svg.selectAll("circle") .data(data) .join( enter => enter.append("circle").attr("fill", "green"), update => update.attr("fill", "blue") ) .attr("stroke", "black");
有關更多示例,請參閱selection.join Observable筆記本。
這至關於通常更新模式:
var circle = svg.selectAll("circle") // 1 .data(data) // 2 .attr("fill", "blue"); // 3 circle.exit().remove(); // 4 circle = circle.enter().append("circle") // 5, 9 .attr("fill", "green") // 6 .merge(circle) // 7 .order() // 8 .attr("stroke", "black"); // 9
將其分解爲不連續的步驟:
svg
選擇)的選擇。data
,返回匹配的圈子:更新選擇。circle
。如前面段落所述,「匹配」邏輯由傳遞給選擇 .data 的鍵函數肯定; 因爲在上面的代碼示例中沒有使用鍵函數,所以元素和數據經過索引鏈接。
返回輸入選擇:佔位符節點,用於選擇中沒有相應DOM元素的每一個數據。(對於selection.data未返回的選擇,輸入選擇爲空。)
輸入選擇一般用於建立與新數據相對應的「缺失」元素。例如,要從數字數組建立DIV元素:
var div = d3.select("body") .selectAll("div") .data([4, 8, 15, 16, 23, 42]) .enter().append("div") .text(function(d) { return d; });
若是正文最初爲空,則上面的代碼將建立六個新的DIV元素,按順序將它們附加到正文,並將其文本內容指定爲關聯的(字符串強制)數字:
<div>4</div> <div>8</div> <div>15</div> <div>16</div> <div>23</div> <div>42</div>
從概念上講,輸入選擇的佔位符是指向父元素的指針(在本例中爲文檔主體)。輸入選擇一般僅暫時用於附加元素,而且一般在附加後與更新選擇合併,使得修改能夠應用於輸入和更新元素。
# selection.exit() <>
返回退出選擇:選擇中沒有找到新數據的現有DOM元素。(對於 selection.data未返回的選擇,退出選擇爲空。)
退出選擇一般用於刪除與舊數據相對應的「多餘」元素。例如,要使用新的數字數組更新先前建立的DIV元素:
div = div.data([1, 2, 4, 8, 16, 32], function(d) { return d; });
因爲指定了鍵函數(做爲標識函數),而且新數據包含與文檔中現有元素匹配的數字[4,8,16],所以更新選擇包含三個DIV元素。將這些元素保留爲原樣,咱們可使用輸入選擇爲[1,2,32]添加新元素:
div.enter().append("div").text(function(d) { return d; });
一樣,要刪除現有元素[15,23,42]:
div.exit().remove();
如今文檔正文以下所示:
<div>1</div>
<div>2</div>
<div>4</div>
<div>8</div>
<div>16</div>
<div>32</div>
DOM元素的順序與數據的順序匹配,由於舊數據的順序和新數據的順序是一致的。若是新數據的順序不一樣,請使用selection.order從新排序DOM中的元素。有關數據鏈接的更多信息,請參閱常規更新模式示例線程。
# selection.datum([value]) <>
獲取或設置每一個選定元素的綁定數據。與selection.data不一樣,此方法不計算鏈接,也不影響索引或輸入和退出選擇。
若是指定了值,則將元素的綁定數據設置爲全部選定元素上的指定值。若是該值是常量,則全部元素都被賦予相同的數據; 不然,若是值是一個函數,則按順序計算每一個選定元素的值,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM element(nodes [ i ])。而後,該函數用於設置每一個元素的新數據。空值將刪除綁定數據。
若是未指定值,則返回選擇中第一個(非null)元素的bound數據。僅當您知道選擇包含一個元素時,這一般頗有用。
此方法對於訪問HTML5 自定義數據屬性頗有用。例如,給出如下要素:
<ul id="list"> <li data-username="shawnbot">Shawn Allen</li> <li data-username="mbostock">Mike Bostock</li> </ul>
您能夠經過將每一個元素的數據設置爲內置數據集屬性來公開自定義數據屬性:
selection.datum(function() { return this.dataset; })
對於交互,選擇容許監聽和分派事件。
# selection.on(typenames[, listener[, options]]) <>
爲指定的事件類型名稱的每一個選定元素添加或刪除偵聽器。所述typenames是一個字符串事件類型,如,,或; 可使用瀏覽器支持的任何DOM事件類型。類型能夠可選地後跟句點()和名稱; 可選名稱容許註冊多個回調以接收相同類型的事件,例如和。要指定多個類型名稱,請使用空格分隔類型名稱,例如或。click
mouseover
submit
.
click.foo
click.bar
input change
click.foo click.bar
當在所選元素上調度指定事件時,將爲元素評估指定的偵聽器,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前值DOM元素(nodes [ i ])。監聽器老是看到其元素的最新數據,但索引是選擇的屬性,而且在分配監聽器時是固定的; 更新索引,從新分配監聽器。要在偵聽器中訪問當前事件,請使用d3.event。
若是事件偵聽器先前已在所選元素上註冊了相同的類型名稱,則在添加新偵聽器以前將刪除舊偵聽器。要刪除偵聽器,請將null做爲偵聽器傳遞。要刪除給定名稱的全部偵聽器,請將null做爲偵聽器並.foo
做爲typename傳遞,其中foo
名稱爲; 刪除全部沒有名稱的偵聽器,指定.
爲typename。
可選的選項對象能夠指定有關事件偵聽器的特徵,例如它是捕獲仍是被動; 請參閱element.addEventListener。
若是收聽者未指定,返回指定事件的當前分配的偵聽類型名稱的第一個(非空)選擇的元素上,若是有的話。若是指定了多個類型名,則返回第一個匹配的偵聽器。
# selection.dispatch(type[, parameters]) <>
按順序將指定類型的自定義事件調度到每一個選定元素。能夠指定可選參數映射以設置事件的其餘屬性。它可能包含如下字段:
bubbles
- 若是爲true,則以反向樹順序將事件分派給祖先。cancelable
- 若是爲true,則容許事件 .preventDefault。detail
- 與事件相關的任何自定義數據。若是參數是一個函數,則按順序計算每一個選定元素的值,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM元素(節點) [ i ])。它必須返回當前元素的參數映射。
# d3.event
當前event,若是有的話。這是在調用事件偵聽器期間設置的,並在偵聽器終止後重置。使用此訪問標準活動領域,如event.timeStamp以及諸如方法event .preventDefault。雖然您可使用本機event .pageX和event .pageY,但使用d3.mouse,d3.touch或d3.touches將事件位置轉換爲接收事件的容器的本地座標系一般更方便。
若是您使用Babel,Webpack或其餘ES6到ES5捆綁器,請注意d3.event的值在事件期間會發生變化!導入d3.event必須是實時綁定,所以您可能須要將捆綁程序配置爲從D3的ES6模塊而不是從生成的UMD包導入; 並不是全部捆綁商都觀察到jsnext:main。還要注意與 window.event全局的衝突。
# d3.customEvent(event, listener[, that[, arguments]]) <>
調用指定監聽器,使用指定的這 方面並經過指定的參數,若是有的話。在調用期間,d3.event設置爲指定的事件 ; 在偵聽器返回(或拋出錯誤)以後,d3.event將恢復爲其先前的值。此外,將事件 .sourceEvent 設置爲d3.event的先前值,容許自定義事件保留對原始本機事件的引用。返回偵聽器返回的值。
# d3.mouse(container) <>
返回當前事件相對於指定容器的x和y座標。容器能夠是HTML或SVG容器元素,例如G元素或SVG元素。座標以數字[ x,y ] 的雙元素數組的形式返回。
# d3.touch(container[, touches], identifier) <>
返回觸摸的x和y座標,其中指定的標識符與當前事件相關的指定標識符相對於指定的容器。容器能夠是HTML或SVG容器元素,例如G元素或SVG元素。座標以數字[ x,y ] 的雙元素數組的形式返回。若是存在與指定的標識符沒有觸摸觸摸,則返回null; 這對於忽略只有一些觸摸移動的touchmove事件很是有用。若是未指定touches,則默認爲當前事件changedTouches屬性。
# d3.touches(container[, touches]) <>
返回與當前事件關聯的觸摸相對於指定容器的x和y座標。容器能夠是HTML或SVG容器元素,例如G元素或SVG元素。座標以數組[[ x1,y1 ],[ x2,y2 ],...] 的雙元素數組的數組的形式返回。若是未指定touches,則默認爲當前事件的touches屬性。
# d3.clientPoint(container, event) <>
返回指定事件相對於指定容器的x和y座標。(事件也能夠是觸摸。)容器能夠是HTML或SVG容器元素,例如G元素或SVG元素。座標以數字[ x,y ] 的雙元素數組的形式返回。
this
對於高級用法,選擇提供自定義控制流的方法。
# selection.each(function) <>
按順序爲每一個選定元素調用指定函數,傳遞當前數據(d),當前索引(i)和當前組(節點),並將其做爲當前DOM元素(nodes [ i ])。此方法可用於爲每一個選定元素調用任意代碼,對於建立同時訪問父數據和子數據的上下文很是有用,例如:
parent.each(function(p, j) { d3.select(this) .selectAll(".child") .text(function(d, i) { return "child " + d.name + " of " + p.name; }); });
有關示例,請參閱Sized Donut Multiples。
# selection.call(function[, arguments…]) <>
只調用指定的函數一次,傳入此選擇以及任何可選參數。返回此選擇。這至關於手動調用函數,但有助於方法連接。例如,要在可重用函數中設置多個樣式:
function name(selection, first, last) { selection .attr("first-name", first) .attr("last-name", last); }
如今說:
d3.selectAll("div").call(name, "John", "Snow");
這大體至關於:
name(d3.selectAll("div"), "John", "Snow");
惟一的區別是,選擇 .CALL老是返回的選擇,而不是所謂的返回值函數,。
name
若是此選擇不包含(非null)元素,則返回true。
返回此選擇中全部(非null)元素的數組。
返回此選擇中的第一個(非null)元素。若是選擇爲空,則返回null。
返回此選擇中的元素總數。
D3 locals容許您定義獨立於數據的本地狀態。例如,在渲染小倍數的時間序列數據時,您可能但願全部圖表使用相同的x-scale,但須要使用不一樣的y -scales來比較每一個度量標準的相對性能。D3 locals由DOM元素肯定範圍:在set上,值存儲在給定元素上; 在get上,從給定元素或定義它的最近祖先檢索該值。
# d3.local() <>
聲明一個新的局部變量。例如:
var foo = d3.local();
好比,每一個地方都是一個獨特的象徵性參考; 不一樣的是,每一個局部的值也由DOM肯定範圍。
# local.set(node, value) <>
設置此本地指定的值節點的值,並返回指定的值。這一般使用selection.each執行:
selection.each(function(d) { foo.set(this, d.value); });varvar
若是您只是設置單個變量,請考慮使用selection .property:
selection.property(foo, function(d) { return d.value; });
# local.get(node) <>
返回指定節點上此local的值。若是節點未定義此local,則返回定義它的最近祖先的值。若是沒有祖先定義此本地,則返回undefined。
# local.remove(node) <>
從指定節點刪除此本地值。若是節點在刪除以前定義了此本地,則返回true,不然返回false。若是祖先也定義了這個本地,那麼這些定義不受影響,所以local.get仍然會返回繼承的值。
# local.toString() <>
返回此本地的自動生成的標識符。這是用於在元素上存儲本地值的屬性的名稱,所以您還可使用元素 [ local ]或使用selection .property來設置或獲取本地值。
XML命名空間頗有趣!對?幸運的是,你能夠忽略它們。
限定指定的名稱,該名稱可能有也可能沒有名稱空間前綴。若是名稱包含冒號(:
),則冒號前的子字符串將被解釋爲名稱空間前綴,該前綴必須在d3.namespaces中註冊。返回描述完整命名空間URL和本地名稱的對象space
和local
屬性。例如:
d3.namespace("svg:text"); // {space: "http://www.w3.org/2000/svg", local: "text"}
若是名稱不包含冒號,則此函數僅返回輸入名稱。
# d3.namespaces <>
已註冊名稱空間前綴的映射。初始值是:
{
svg: "http://www.w3.org/2000/svg", xhtml: "http://www.w3.org/1999/xhtml", xlink: "http://www.w3.org/1999/xlink", xml: "http://www.w3.org/XML/1998/namespace", xmlns: "http://www.w3.org/2000/xmlns/" }
能夠根據須要分配附加前綴以在其餘命名空間中建立元素或屬性。