Animation d3动画中的退出/更新功能

Animation d3动画中的退出/更新功能,animation,d3.js,transitions,Animation,D3.js,Transitions,我正在尝试制作一个动画,显示来自十个不同点的数据。对图形进行编码,以使传感器(通过圆圈显示)根据一小时内获得的总体数据(输入总数和平均速度)改变其颜色和大小 通过这个条目()和Gapminder()模拟中的代码,我已经能够为图表制作动画。但是,由于代码的结构,退出和更新功能不起作用。第1小时数据中的第一个条目只有一个对象,因此只绘制一个圆。这个圆会随着时间而更新,但其他传感器不会被绘制(因此不会更新) 我正在考虑为每个传感器重新创建第一个空对象,以便在动画开始时绘制它们。然而,我想避免这种情况

我正在尝试制作一个动画,显示来自十个不同点的数据。对图形进行编码,以使传感器(通过圆圈显示)根据一小时内获得的总体数据(输入总数和平均速度)改变其颜色和大小

通过这个条目()和Gapminder()模拟中的代码,我已经能够为图表制作动画。但是,由于代码的结构,退出和更新功能不起作用。第1小时数据中的第一个条目只有一个对象,因此只绘制一个圆。这个圆会随着时间而更新,但其他传感器不会被绘制(因此不会更新)

我正在考虑为每个传感器重新创建第一个空对象,以便在动画开始时绘制它们。然而,我想避免这种情况

代码如下:

//FUNCTION TO GET THE DATA BY HOUR
function getDataByHour (hour) {
    var allBridges = new Array();
    var found;
    for (b = 0; b < boatsByHour.length; b++){
        bridges.forEach(function(br,i){
            if (boatsByHour[b].sensorID== br.id){
                xy = projection([br.longitude, br.latitude])}
        });
        if (boatsByHour[b].hour == hour){
            found = true;
            bridgeNumber = boatsByHour[b].sensorID;
            allBridges.push({
                "numberBoats": (boatsByHour[b].numberBoats),
                "speed": (boatsByHour[b].speedAvg),
                "bridge": boatsByHour[b].sensorID,
                "longitude": xy[0],
                "latitude": xy[1],
                "hour": boatsByHour[b].hour
            })
        }
    }
    return allBridges;
}

//SENSORS
var sensor = plot.append("g")
    .attr("class","bridges")
    .selectAll(".sensors")
    .data(getDataByHour(timeRange[0]))
    .call(animateSensors)
    .enter()
    .append("circle")
    .attr("class","sensors")
    .attr("cx", function(d,i){return d.longitude})
    .attr("cy", function(d,i){return d.latitude})
    .on("mouseover",function(d){console.log(d)});

sensor.exit().remove();

plot
    .transition()
    .duration(300000)
    .ease(d3.easeLinear)
    .tween("hour", tweenHour)

//FUNCTION THAT UPDATES THE ANIMATION
function animateSensors (sensor){
    sensor
        .attr("r",function(d){return radiusScale(d.numberBoats)})
        .style("fill",function(d){return colorScale(d.speed)});
}

function tweenHour(){
    var hour = d3.interpolateNumber (timeRange[0],timeRange[1]);

    return function(h){
        displayHour(hour(h))}
}

function displayHour(hour) {
    sensor.data(getDataByHour(Math.floor(hour))).call(animateSensors);
}
//按小时获取数据的函数
函数getDataByHour(小时){
var allBridges=新数组();
var发现;
对于(b=0;b
我尝试了包括enter()和exit()的不同方法。如果我添加enter()并在“animatesesensors”函数中附加圆,则会绘制所有圆(传感器)。但是,它们没有被更新,因此在最后,我在SVG中绘制了数千个圆圈,即使exit().remove()更新在其中


谢谢

好的,现在可以了。我没有调用数据的第一部分(只画了一个圆而不是总共10个),而是调用了所有圆都有数据的数据(如最后一点):

由于函数tweenHour,动画将正确启动

function tweenHour(){
        var hour = d3.interpolateNumber (timeRange[0],timeRange[1]);

        return function(h){
            displayHour(hour(h))}
    }

好的,现在它工作了。我没有调用数据的第一部分(只画了一个圆而不是总共10个),而是调用了所有圆都有数据的数据(如最后一点):

由于函数tweenHour,动画将正确启动

function tweenHour(){
        var hour = d3.interpolateNumber (timeRange[0],timeRange[1]);

        return function(h){
            displayHour(hour(h))}
    }

这个函数更新圆的半径和填充属性
function animatesesensors(sensor){sensor.attr(“r”,function(d){return radiuscale(d.numberbats)}).style(“fill”,function(d){return colorScale(d.speed)};}
调用的位置不会改变结果(仅显示一个圆圈)。我已经检查过,问题是所有数据都直接进入该圆圈,而不是绘制其他圆圈,
allBridges
是一个对象数组。这些对象的选择取决于时间属性
hour
这里的问题是
sensor
是一个“输入”因此,该方法应该创建一个“更新”选择,即:
var sensor=plot.append(“g”).attr(“class”、“bridges”).selectAll(.sensors”).data(getDataByHour(timeRange[0]))
,一个“enter”选择,即:
sensor.enter().append(“圆”)等。
和一个“退出”选项,即:
sensor.exit().remove()
。是的,我昨天试过了,但是如果我这样做的话,就根本没有输入
animatesesensors
功能。我有
传感器…..数据(getDataByHour(timeRange[0]);
然后
sensorEnter
(不调用动画);然后是
sensor.exit().remove();
最后是`sensor.transition().duration(500).call(animatesesensors)`是更新圆的半径和填充属性的函数
function animatesesensors(sensor){sensor.attr(“r”,function(d){return radiusScale(d.numberbats)}).style(“fill”,函数(d){return colorScale(d.speed)};}
调用的位置不会改变结果(只显示一个圆圈).我已经检查过了,问题是所有数据都直接进入该圆圈,而不是绘制另一个圆圈,
allBridges
是一个对象数组。这些对象的选择取决于时间属性
hour
这里的问题是
sensor
是一个“回车”选择,您不能调用
exit()
在“输入”选择上。因此,该方法应该创建一个“更新”选择,即:
var sensor=plot.append(“g”).attr(“class”、“bridges”).selectAll(“sensors”).data(getDataByHour(ti