D3数据更新无法正常工作

时间:2014-01-23 11:36:14

标签: d3.js

我以为我理解D3进入/更新/退出,但我在实现示例时遇到问题。 http://jsfiddle.net/eamonnmag/47TtN/中的代码说明了我正在做的事情。如您所见,每隔5秒钟,我会增加一个项目的评级,然后再次更新显示。这在某种程度上起作用。问题是只更新已更改的内容 - 在这种情况下,D3正在更新所有内容。进入和退出方法,在控制台输出中显示没有任何改变,这使我认为它将每个数组视为一个全新的实例。

我对selectAll()和data()调用的理解是,它会将所有数据“绑定”到幕后某个地方名为“巧克力”的地图,然后做一些逻辑来检测不同的内容。

var chocolate = svg.selectAll("chocolates").data(data);

在这种情况下,这不是正在发生的事情。这是更新代码。任何指向我错过的内容都非常感谢!

function update(data){
    var chocolate = svg.selectAll("chocolates").data(data);

    var chocolateEnter = chocolate.enter().append("g").attr("class", "node");

    chocolateEnter.append("circle")
    .attr("r", 5)
    .attr("class","dot")
    .attr("cx", function(d) {return x(d.price)})
    .attr("cy", function(d) { 
    //put the item off screen, to the bottom. The data item will slide up.
        return height+100;})
    .style("fill", function(d){ return colors(d.manufacturer); });

    chocolateEnter
        .append("text")
        .text(function(d) {
        return d.name;})
        .attr("x", function(d) {return x(d.price) -10})
        .attr("y", function(d){return y(d.rating+step)-10});

    chocolateEnter.on("mouseover", function(d) {
        d3.select(this).style("opacity", 1);
    }).on("mouseout", function(d) {
        d3.select(this).style("opacity", .7);
    })

    chocolate.selectAll('circle')
        .transition().duration(500)
        .attr('cy', function(d) {return y(d.rating+step)});


    var chocolateExit = chocolate.exit().remove();
    chocolateExit.selectAll('circle')
    .attr('r', 0);
}

setInterval(function() {    
    chocolates[3].rating = Math.min(chocolates[3].rating+1, 5);
    update(chocolates);

}, 5000);

2 个答案:

答案 0 :(得分:1)

Easy as apple pie!

你为什么要做svg.selectAll("chocolates")?您的DOM中没有名为chocolates的HTML元素。 您需要将其更改为svg.selectAll(".node")。这将解决问题。

答案 1 :(得分:1)

您的代码中存在一些问题。首先,默认情况下,检测不同内容的逻辑是使用项目的索引。也就是说,第一个数据项与第一个DOM元素匹配,依此类推。这适用于您的情况,但如果您传入部分数据,则会中断。我建议使用.data()的第二个参数告诉它如何匹配:

 var chocolate = svg.selectAll("g.node").data(data, function(d) { return d.name; });

其次,正如另一张海报所指出的那样,选择“巧克力”将不会选择任何东西,因为没有这样的DOM元素。只需选择实际的元素即可。

最后,由于您要为数据项添加g元素,因此您也可以使用它们。我的意思是,目前,您正在单独处理圆圈和文本,并且必须更新它们。但是,您可以将所有内容放在g元素下面。然后你必须只更新那些,这简化了你的代码。

我在您修改过的小提琴here中进行了以上所有更改。