D3JS散点图刷新速度

D3JS Scatter plots refresh speed

我想知道是否有办法改变散点图的刷新速度? 正如您在此 link 中看到的那样,散点图已更新,但出现和消失之间的时间间隔不合理,看起来它们是闪烁的点....我尝试移动 circle.remove()在 circle.transition 上方运行,但没有区别。

下面是刷新函数的相关代码。谢谢!

function updateData() {

    // Get the data again
    data = d3.json("2301data.php", function(error, data) {
    data.forEach(function(d) {
        d.dtg = parseDate(d.dtg);
        d.temperature = +d.temperature;
       // d.hum = +d.hum; // Addon 9 part 3
    });

     // Scale the range of the data again 
     x.domain(d3.extent(data, function(d) { return d.dtg; }));
     y.domain([0, 60]);             

    var svg = d3.select("#chart1").select("svg").select("g");

                svg.select(".x.axis") // change the x axis
            .transition()
            .duration(750)
            .call(xAxis);
        svg.select(".y.axis") // change the y axis
            .transition()
            .duration(750)
            .call(yAxis);
        svg.select(".line")   // change the line
            .transition()
            .duration(750)
            .attr("d", valueline(data));

    var circle = svg.selectAll("circle").data(data);

    circle.remove() //remove old dots   

    // enter new circles
        circle.enter()
            .append("circle")
            .filter(function(d) { return d.temperature > 35 })
            .style("fill", "red")   
            .attr("r", 3.5) 
            .attr("cx", function(d) { return x(d.dtg); })
            .attr("cy", function(d) { return y(d.temperature); })

        // Tooltip stuff after this
        .on("mouseover", function(d) {      
            div.transition()
                .duration(500)  
                .style("opacity", 0);
            div.transition()
                .duration(200)  
                .style("opacity", .9);  
            div .html(
                d.temperature + "C" + "<br>" +
                formatTime(d.dtg)) 
                .style("left", (d3.event.pageX + 8) + "px")          
                .style("top", (d3.event.pageY - 18) + "px");})
        .on("mouseout", function(d) {       
            div.transition()        
                .duration(500)      
                .style("opacity", 0);   
            });

    circle.transition().attr("cx", function(d) { return x(d.dtg); });   
        // exit 
        circle.exit();



    });
}

查看您的示例 运行s,您似乎在 dom 中加载了比可见更多的圆圈。这是因为您为所有数据添加了圈子,但随后只为满足您设置的过滤条件的那些人提供位置。

前几天有一个关于数据过滤与 d3 过滤的相关问题 - 。如果你不想添加句号,请使用数据过滤,如果你想隔离一些元素进行特殊处理(转换、不同的样式等),请使用 d3.filter。

目前您在添加所有圆圈后过滤 d3 选择,但在您的情况下,我建议在数据到达该阶段之前过滤数据是最好的(并且正如其他人所建议的那样)题)。这可能会使它 运行 更快(但从您的示例来看,您还受数据库更新的支配?)

data = data.filter (function(d) { return d.temperature > 35; }); // do filtering here
var circle = svg.selectAll("circle").data(data);

circle.exit().remove() //remove old dots   

// enter new circles
    circle.enter()
        .append("circle")
        .style("fill", "red")   
        .attr("r", 3.5) 
        .attr("cx", function(d) { return x(d.dtg); })
        .attr("cy", function(d) { return y(d.temperature); })
        ...

PS。你试图用 circle.remove() 和 circle.exit() 做什么有点令人困惑。 circle.remove() 将删除所有现有的圈子(即使是那些存在并具有新数据的圈子),最后的 circle.exit() 将没有任何效果。我只需要 circle.exit().remove() 来替换您拨打的两个电话。

此外,如果没有关键功能 - https://bost.ocks.org/mike/constancy/ - 在您的 .data() 调用中,您可能会发现点会稍微移动。如果您的数据点有 ID,请使用它们。

var circle = svg.selectAll("circle").data(data, function(d) { return d.id; /* or d.dtg+" "+d.temperature; if no id property */});

多亏了 mgraham,问题解决了!以下是修改后的代码,以防其他人需要。

function updateData() {

    // Get the data again
    data = d3.json("data.php", function(error, data) {
    data.forEach(function(d) {
        d.dtg = parseDate(d.dtg);
        d.temperature = +d.temperature;
      });

       // Scale the range of the data again 
     x.domain(d3.extent(data, function(d) { return d.dtg; }));
     y.domain([0, 60]); // Addon 9 part 4

    var svg = d3.select("#chart1").select("svg").select("g");

    svg.select(".x.axis") // change the x axis
            .transition()
            .duration(750)
            .call(xAxis);
        svg.select(".y.axis") // change the y axis
            .transition()
            .duration(750)
            .call(yAxis);
        svg.select(".line")   // change the line
            .transition()
            .duration(750)
            .attr("d", valueline(data));


    data = data.filter (function(d) { return d.temperature > 35; }); 

    var circle = svg.selectAll("circle").data(data, function(d) { return d.dtg+" "+d.temperature;});
    circle.exit().remove() //remove old dots   

    // enter new circles
        circle.enter()
             .append("circle")
         .style("fill", "red")  
         .attr("r", 3.5)    
             .attr("cx", function(d) { return x(d.dtg); })
         .attr("cy", function(d) { return y(d.temperature); })

    // Tooltip stuff after this
        .on("mouseover", function(d) {      
            div.transition()
                .duration(500)  
                .style("opacity", 0);
            div.transition()
                .duration(200)  
                .style("opacity", .9);  
            div .html(
                d.temperature + "C" + "<br>" +
                formatTime(d.dtg)) 
                .style("left", (d3.event.pageX + 8) + "px")          
                .style("top", (d3.event.pageY - 18) + "px");})
        .on("mouseout", function(d) {       
            div.transition()        
                .duration(500)      
                .style("opacity", 0);   
            });

    circle.transition().attr("cx", function(d) { return x(d.dtg); });   


    });
}         

</script>