2014-10-11 19 views
1

我想刪除單擊的欄,但出於某種原因,它總是刪除最後一個欄。我認爲答案可能在以下文章(http://pothibo.com/2013/09/d3-js-how-to-handle-dynamic-json-data/)中,但我不確定是否需要手動爲每個元素分配鍵。我花了幾個小時試圖讓這個工作,所以我希望有人能指出我在正確的方向。提前致謝。刪除不正確的SVG組

<html> 
<head> 
    <title>Interactive Div-based Bar Chart</title> 
    <style type="text/css"> 
    .chart rect { 
     fill: teal; 
    } 
    .chart text { 
     fill: white; 
     font: 30px sans-serif; 
     text-anchor: end; 
    } 
    </style> 
    <script src="Scripts/d3.min.js"></script> 
</head> 
<body> 
    <div id="data-field"></div> 
    <button id="add-btn">Add Data</button> 
    <p>Click on a bar to remove it</p> 

    <script> 
     var barHeight = 75, margin = 3, padding = 3; 

     var chartData = [6,12,15,21,29,41]; 

     var chart = d3.select("body").append("svg").attr("class","chart"); 

     drawChart(); 

     function drawChart() { 

      var selection = chart.selectAll("g") 
       .data(chartData); 

      // Remove extra bars 
      selection.exit() 
       .remove(); 

      // Add more bars 
      var groups = selection.enter() 
       .append("g"); 

      var bars = groups 
       .append("rect"); 

      var labels = groups 
       .append("text"); 

      // Update existing bars 
      groups 
       .attr("transform", function (d, i) { return "translate(0," + i * (barHeight + margin) + ")"; }) 
       .on("click", function (d, i) { chartData.splice(i, 1); drawChart(); });  

      bars 
       .attr("width", function (d) { return d * 10 + "px"; }) 
       .attr("height", barHeight);  

      labels 
       .attr("x", function (d) { return d * 10 - padding + "px"; }) 
       .attr("y", barHeight/3 + padding + "px") 
       .text(function (d) { return d; }); 

      // update list of numbers 
      d3.select("#data-field").text("numbers: [" + chartData.join(", ") + "]"); 
     } 

     // add more data 
     d3.select("#add-btn") 
      .on("click", function(d) { chartData.push(Math.round(Math.random() * 100)); drawChart(); }); 

    </script> 

</body> 
</html> 
+1

plz put in fddle – 2014-10-11 03:28:24

+0

http://jsfiddle.net/zxg02fdm/1/ – loucatsfan 2014-10-14 13:50:05

回答

1

這裏有您需要的變化,評論說:

// Update existing bars; do not use groups here since it represents 
// only the ENTER selection, and not ALL g elements 
selection 
    .attr("transform", function (d, i) { return "translate(0," + i * (barHeight + margin) + ")"; }) 
    .on("click", function (d, i) { 
     d3.select(this).remove(); // remove appropriate DOM element 
     chartData.splice(i, 1); 
     drawChart(); 
    }); 

這裏是FIDDLE

重要編輯:

@loucatsfan後問我,爲什麼不乾脆擺脫selection.exit().remove();,因爲它並沒有區別,我意識到讓我的回答更加慣用的重要性。所以,我創建了一個更新的小提琴,它利用了exit選擇並消除了手動刪除DOM元素的需要。

此外,同樣重要的是,處理分組與非分組元素的更新(使用selectselectAll)之間存在一些細微差異。所以,我修改了代碼以更好地處理分組元素。

你可以找到更多的信息正確處理分組元素herehere。但這是承諾的改進:

UPDATED FIDDLE

+0

非常感謝。這讓我瘋狂。 – loucatsfan 2014-10-17 15:50:24

+0

我非常感謝您付出額外的努力來給出一個使用輸入/退出/更新模式的解決方案。雖然顯然有其他方法可以解決這個問題,但我更喜歡遵循最佳實踐。你是一個紳士和學者。非常感謝我和所有閱讀這篇文章的人。 – loucatsfan 2014-10-19 02:56:21

2

這裏查看我的解決方案:http://fiddle.jshell.net/sydvpsfp/

主要問題是,你是不是在drawChart功能的開頭刪除所有老筋。 我又增加了這一點:

 // remove any old bars 
     var oldBars=chart.selectAll("g"); 
     if (oldBars.size()>0) 
      oldBars.remove(); 
+0

loucatsfan:有沒有反饋?這對你有用嗎? – slotomo 2014-10-12 19:03:16

+0

我從來沒有收到關於你的帖子的電子郵件,所以我猜它已經到了垃圾箱。無論如何,我希望能夠在不去除所有情況的情況下繼續工作。如果我刪除所有內容,則不需要退出方法。 – loucatsfan 2014-10-13 23:47:15

+0

在這種情況下,您應該刪除單擊的欄並重新排列其他欄,而不必每次調用drawChart。 – slotomo 2014-10-14 13:17:38