2017-05-06 45 views
1

我正在構建一個交互式的散點圖,我無法更新圓圈的選擇(數據點SEEM工作正常,但我無法確定,因爲行爲有點不穩定)。當我創建一個初始繪圖時,點和線顯示正常,但是在單擊節點並將其移除後,我無法重置選擇。更具體地說,變量「我」(在我的理解中給出了選擇對象的索引)仍然受限於初始選擇。代碼如下:更新D3對象的選擇

 function mousedownCircle(d, i) { 
      console.log(i); 
      circles[0][i].remove(); 
      dataset.splice(i, 1); 
      circles = svg.selectAll("circle").data(dataset); 
      line_obj.attr("d", valueline(dataset)); 
      d3.event.stopPropagation(); 
     } 

     // Create Circles 
     var circles = svg.selectAll("circle") 
      .data(dataset) 
      .enter() 
      .append("circle") // Add circle svg 
      .attr("cx", function(d) { 
       return xScale(d[0]); // Circle's X 
      }) 
      .attr("cy", function(d) { // Circle's Y 
       return yScale(d[1]); 
      }) 
      .attr("r", radius) // radius 
      .on("click", mousedownCircle); // click callback 

主要想法是能夠刪除圓和數據點。我究竟做錯了什麼?

謝謝你的時間!

+2

您不必刪除的圈子:只是刪除數據點使用「更新」+「退出」選擇。然而,對於任何人在這裏幫助你,你必須發佈一個工作代碼和數據結構。 –

回答

0

d3的關鍵是遵循正確的enter,update,exit模式。我通常會將它封裝到一個函數中,而不管動作如何「重繪」我的可視化。從看你的代碼片段,一個適當的功能將類似於:

function update() { 

    // Create Circles 
    var circles = svg.selectAll("circle") 
    .data(dataset); 

    circles.exit().remove(); // remove the ones exiting 

    circles = circles 
    .enter() // Add circle to svg 
    .append("circle") 
    .merge(circles); // this is the update + enter selection 

    circles // update circles 
    .attr("cx", function(d) { 
     return xScale(d[0]); // Circle's X 
    }) 
    .attr("cy", function(d) { // Circle's Y 
     return yScale(d[1]); 
    }) 
    .attr("r", 40) // radius 
    .style("fill", "steelblue") 
    .on("click", mousedownCircle); // click callback 
} 

mousedownCircle功能則變得異常簡單:

function mousedownCircle(d, i) { 
    dataset.splice(i, 1); 
    update(); 
} 

運行例如:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
</head> 
 

 
<body> 
 
    <script> 
 
    function mousedownCircle(d, i) { 
 
     dataset.splice(i, 1); 
 
     update(); 
 
    } 
 

 
    var w = 400, 
 
     h = 400; 
 

 
    var svg = d3.select('body') 
 
     .append('svg') 
 
     .attr('width', w) 
 
     .attr('height', h); 
 

 
    var dataset = [ 
 
     [Math.random() * w, Math.random() * h], 
 
     [Math.random() * w, Math.random() * h], 
 
     [Math.random() * w, Math.random() * h], 
 
     [Math.random() * w, Math.random() * h], 
 
     [Math.random() * w, Math.random() * h], 
 
     [Math.random() * w, Math.random() * h] 
 
    ]; 
 

 
    update(); 
 

 
    function update() { 
 

 
     // Create Circles 
 
     var circles = svg.selectAll("circle") 
 
     .data(dataset); 
 

 
     circles.exit().remove(); 
 

 
     circles = circles 
 
     .enter() 
 
     .append("circle") 
 
     .merge(circles); // Add circle svg 
 
     
 
     circles 
 
     .attr("cx", function(d) { 
 
      return d[0]; // Circle's X 
 
     }) 
 
     .attr("cy", function(d) { // Circle's Y 
 
      return d[1]; 
 
     }) 
 
     .attr("r", 40) // radius 
 
     .style("fill", "steelblue") 
 
     .on("click", mousedownCircle); // click callback 
 

 
    } 
 
    </script> 
 
</body> 
 

 
</html>

迴應評論

最直接的方式做你是什麼之後將是:

<!DOCTYPE html> 
 
<html> 
 

 
<head> 
 
    <script data-require="[email protected]" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script> 
 
</head> 
 

 
<body> 
 
    <script> 
 
    function mousedownCircle(d, i) { 
 
     d3.select(this).remove(); 
 
    } 
 

 
    var w = 400, 
 
     h = 400; 
 

 
    var svg = d3.select('body') 
 
     .append('svg') 
 
     .attr('width', w) 
 
     .attr('height', h); 
 

 
    var dataset = [ 
 
     [Math.random() * w, Math.random() * h], 
 
     [Math.random() * w, Math.random() * h], 
 
     [Math.random() * w, Math.random() * h], 
 
     [Math.random() * w, Math.random() * h], 
 
     [Math.random() * w, Math.random() * h], 
 
     [Math.random() * w, Math.random() * h] 
 
    ]; 
 

 

 
    // Create Circles 
 
    var circles = svg.selectAll("circle") 
 
     .data(dataset) 
 
     .enter() 
 
     .append("circle") 
 
     .attr("cx", function(d) { 
 
     return d[0]; // Circle's X 
 
     }) 
 
     .attr("cy", function(d) { // Circle's Y 
 
     return d[1]; 
 
     }) 
 
     .attr("r", 40) // radius 
 
     .style("fill", "steelblue") 
 
     .on("click", mousedownCircle); // click callback 
 
    </script> 
 
</body> 
 

 
</html>

+0

謝謝馬克。我也會爲你更新一個小小的更新而煩惱 - 在我的執行過程中,本質的想法是「最佳」,而不是更新不受點擊影響的圓圈,只是刪除/更改的圓圈。這是否合理?我如何定位一個圓圈?或者這是不好的做法? –

+0

@CindyAlmighty,查看上面的更新。 – Mark