2014-05-20 80 views
2

所有的問題,我都無法更新我用D3繪製的一些圓圈的值。整個代碼在下面。D3將數值更新爲鼠標點擊的新數據集

您將看到數據集1中有3個值,數據集2中有4個值。

我只需要做的就是更新鼠標點擊從dataset1到dataset2按鈕的圓圈。

但是,當我運行此代碼時,只更新dataset2的前三個值,第四個值丟失。這必須與數據集1只有3個值並因此只更新數據集2中的前3個值這一事實有關。

欣賞一個響應,告訴我我需要做的不僅僅是更新什麼。我搜查了很多,但大多數回覆都是模糊的。

非常感謝您的幫助。

後完全展開FIDDLE代碼
<html> 
<head> 
    <script type="text/javascript" src="d3/d3.js"> </script> 
    <title>update data</title> 
    <meta charset="UTF-8"> 
    <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
</head> 
<body> 
<p id = "h">test</p> 
<button onclick="fader()">Click me</button> 
<script>  



var dataset1 = [30,90,150]; 
var dataset2 = [5,30,100,79]; 

d3.selectAll("#h") 
.append("svg") 
.attr("width",200) 
.attr("height",200) 

.selectAll("circle") 
.attr("id","mastercircle")   
.append("svg") 
.data(dataset1) 
.enter() 
.append("circle") 
.attr("id","mycircle")  
.attr("cy", 90) 
.attr("cx", String) 
.attr("r", Math.sqrt) 
.attr("fill","green") 


.style("opacity", 1) 
.transition().duration(600) 
.style("opacity", 0.5)  
    ; 

    function fader() { 


     d3.selectAll("#mycircle") 

     .data(dataset2) 

    .attr("cy", 90) 
    .attr("cx", String) 
    .attr("r", Math.sqrt) 
    .attr("fill","red") 
    .style("opacity", 1) 
    .transition().duration(1000) 
    .style("opacity", 0.5)  

    ; 

    }; 


    </script> 


</body> 
</html> 

見代碼。它現在添加新數據但不刪除舊數據。感謝您如果能告訴我我需要退出並移除的位置?

只是試圖瞭解到底發生了什麼,而沒有使用變量來理解D3實際上在做什麼。

<html> 
    <head> 
     <script type="text/javascript" src="d3/d3.js"> </script> 
     <title>Delete</title> 
     <meta charset="UTF-8"> 
     <meta name="viewport" content="width=device-width, initial-scale=1.0"> 
    </head> 
    <body> 
    <p id = "h">test</p> 
     <button id = "update">Click me</button> 
<script>  



var dataset1 = [30, 90, 150]; 
var dataset2 = [5, 30, 100, 79]; 

d3.select("#h") //p must be loaded for this to work i.e. above the code 
    .append("svg") 
    .attr("width",200) 
    .attr("height",200) 

    .selectAll("circle") 
    .data(dataset1) 

//sel above 

    .enter() 
    .append("circle") 
    .attr("class","circles") 


    .attr("cy", 90) 
    .attr("cx", String) 
    .attr("r", Math.sqrt) 
    .attr("fill","green")  
    .style("opacity", 1) 
    .transition().duration(600) 
    .style("opacity", 0.5)  
    ; 

function fader() { 


d3.select("#h") 

.append("svg") 
    .attr("width",200) 
    .attr("height",200) 
    //.selectAll("circle") 
    //.data(dataset1) 
    .selectAll(".circles") 
    .data(dataset2) 



     .enter() // enter selection 
     .append("circle") 
     .attr("class", "circles") 

     //update selection 
     .transition().duration(1000) 
     .attr("cy", 90) 
     .attr("cx", String) 
     .attr("r", Math.sqrt) 
     .attr("fill", "red") 
     .style("opacity", 1)  
     .style("opacity", 0.5) ; 

}; 

d3.select("#update").on("click", fader); 



</script> 


    </body> 
</html> 

回答

3

有大量的資源在理解輸入/更新/退出模式,一個最流行的是通過Thinking with Joins D3的創造者。

我已將這一重要模式應用於您的代碼並將其置於此FIDDLE。您可以查看代碼(包含關鍵評論)並與Mike的帖子中的解釋進行比較。

sel 
    .enter() // enter selection 
    .append("circle") 
    .attr("class", "circles"); 

sel //update selection 
    .attr("cy", 90) 
    .attr("cx", String) 
    ... 

注意:一個經常被忽視的方面是給一個特定的類來繪製,這樣就可以通過這個類是指他們當你想更新它們或以任何其他方式處理這些元素的重要性(代碼中的類circles)。我還將第二個轉換移到了較早的點,以便您可以清楚地看到要添加到該組的新的圓以及正確的位置。

+0

非常感謝,閱讀了大約5次FIDDLE後,我想我明白髮生了什麼。我從來沒有遇到過退出和移除的適當例子。我不明白的一件事是,爲什麼在應用之前退出選擇?即Sel.exit()。remove()...然後你繼續輸入()??。我會閱讀你的鏈接。而你的FIDDLE例子非常清楚,儘管我不明白這個刪除和退出很好。乾杯。 – user2259146

+0

您可以在輸入/更新之後放置退出選擇......它並不重要......這些是D3已經預定/分配用於移除的元素,並且不參與輸入/更新選擇。在你的例子中,退出選擇並不是真的需要,因爲你沒有刪除任何元素......但是我總是使用它,因爲它沒有傷害,當你需要時它會在那裏。它構成了一個很好的習慣:) – FernOfTheAndes

+0

謝謝,最後一件事,什麼d3.select(「#update」)。on(「click」,fader);實際上呢?我知道它參考了推子功能。我原來的按鈕是點擊我。我想這不是以任何方式引用D3? – user2259146