2017-07-13 56 views
3

我有一段代碼在點擊按鈕時調用。使用'attr()'時的選擇差異

const lines = svg.select('lines').selectAll('line').data(arr); 
lines.enter().append('line'); 
lines 
    .attr('x1', d => d) 
    .attr('y1', d => d) 
    .attr('x2', d => d+2) 
    .attr('y2', d => d+2) 
    .attr('stroke-width', 2); 

當我按一下按鈕沒有任何顯示,但在點擊按鈕第二次的線可以看出。

所以我試圖鏈接.attr()只有.append()。 像這樣:

const lines = svg.select('lines').selectAll('line').data(arr); 
    lines.enter().append('line') 
     .attr('x1', d => d) 
     .attr('y1', d => d) 
     .attr('x2', d => d+2) 
     .attr('y2', d => d+2) 
     .attr('stroke-width', 2); 

這一次的線可以在按鈕的第一次點擊可以看到。

我只是想知道這種行爲背後的原因。

+1

我改變你的問題標題對於未來更容易被發現和引用的東西(這是SO的主要目標之一),請隨意如果你願意的話可以把它推回去。 –

回答

6

在您的第一個代碼片段中,您正在對變量執行.attr。這是持有update選擇(頁面上已選擇那些東西)。由於什麼都不存在,所以沒有什麼可以更新的。

在第二代碼段,你在事情.append方法(通過鏈)返回執行.attr。那些東西剛剛被.enter添加到頁面,並且是enter選擇。

4

除了@馬克的(正確)answer,值得一提的是,您的這個片段將在D3 v3.x中工作

發生了什麼事是D3創建者Mike Bostock在D3 v3中引入了神奇行爲,他保留在D3 v3.x中,但決定放棄在D3 v4.x中。要了解更多有關,看看這裏:What Makes Software Good?這是他說的話:

D3 2.0中引入的改變:追加到輸入選擇現在將進入元素複製到更新的選擇[...] D3 4.0消除了enter.append的魔力。 (事實上​​,D3 4.0完全消除了輸入和普通選擇之間的區別:現在只有一個選擇類別。)

這是使用D3 v4.x的代碼演示。什麼都不會顯示出來,你可以看到:

const arr = [10, 20, 30] 
 
const svg = d3.select("svg"); 
 
const lines = svg.selectAll('line').data(arr); 
 
lines.enter().append('line'); 
 
lines.attr('x1', d => d) 
 
    .attr('y1', d => d) 
 
    .attr('x2', d => d + 40) 
 
    .attr('y2', d => d + 20) 
 
    .attr('stroke-width', 2) 
 
    .attr("stroke", "black");
<script src="https://d3js.org/d3.v4.min.js"></script> 
 
<svg></svg>

現在完全相同的代碼,使用D3 V3:

const arr = [10, 20, 30] 
 
const svg = d3.select("svg"); 
 
const lines = svg.selectAll('line').data(arr); 
 
lines.enter().append('line'); 
 
lines.attr('x1', d => d) 
 
    .attr('y1', d => d) 
 
    .attr('x2', d => d + 40) 
 
    .attr('y2', d => d + 20) 
 
    .attr('stroke-width', 2) 
 
    .attr("stroke", "black");
<script src="https://d3js.org/d3.v3.min.js"></script> 
 
<svg></svg>

+0

這解釋@ Mark的答案。謝謝 – vs1682