D3在鼠标单击时将值更新为新数据集

时间:2014-05-20 18:34:11

标签: javascript svg d3.js

全部,我无法更新我用D3绘制的某些圆圈的值。整个代码如下。

您将看到dataset1中有3个值,dataset2中有4个值。

我只想做的就是在数据集1到数据集2的鼠标点击按钮时更新圆圈。

但是,当我运行此代码时,只更新了dataset2的前三个值,缺少第四个值。这必须与dataset1只有3个值,因此只更新dataset2中的前3个值这一事实有关。

欣赏一个回复,告诉我我需要做什么,而不仅仅是做什么,做更新等等。我搜索了很多,但大多数回复都很模糊。

非常感谢你的帮助。

    <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>

完全展开FIDDLE代码后查看代码。它现在添加新数据但不删除旧数据。如果你能告诉我退出和删除的位置,感激不尽?

只是尝试在不使用变量的情况下准确了解正在发生的事情,以了解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>

1 个答案:

答案 0 :(得分:3)

有很多资源可以理解输入/更新/退出模式,其中最受欢迎的是D3的创建者Thinking with Joins

我已将此重要模式应用于您的代码并将其放在此FIDDLE中。您可以查看代码(带有关键注释)并与Mike的帖子中的解释进行比较。

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

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

注意:一个常被忽视的方面是为您绘制的元素提供特定类的重要性,以便在您想要更新它们或以任何其他方式处理它们时,可以通过此类引用它们(类{{1在代码中)。我还将第二个过渡移动到较早的点,这样您就可以清楚地看到新的圆圈被添加到组中,并且位于正确的位置。