使用数据生成具有d3过渡方法的散点图

时间:2014-10-30 13:10:51

标签: javascript csv d3.js transition scatter-plot

我正在尝试这样做:http://bost.ocks.org/mike/nations/

然而,当我在时间轴中点击每年的按钮时,我希望转换显示而不是鼠标悬停时的转换。

csv文件中的一些示例数据:

time,name,xAxis,yAxis,radius,color
1990,America,10,20.2,30,black
1990,China,50,50,50,yellow
2000,Singapore,20,30,20,red
2010,China,60,50,50,yellow
2020,America,20,30,40,black
2020,Malaysia,60,5,10,orange

我是javascript和d3的新手,我遇到了转换问题。我希望圈子对每个名字(美国,中国,新加坡,马来西亚)都是唯一的,这样我每个名字只会有一个圆圈。当我点击相应的时间线按钮时,新的圈子会添加,但不会转移到新的位置或退出。

使用d3.csv读取数据:

d3.csv("data.csv", function(dataset) {
    var years = [];
    data=dataset;

    //create a button for each year in the timeline
    dataset.forEach(function(d){
        console.log(d.time);

        //if not existing button for timeline
        if($.inArray(d.time, years) == -1)
        {
            var button = document.createElement("button");
            button.setAttribute("type", "button"); 
            button.setAttribute("class", "btn btn-default");
            button.setAttribute('onclick', 'update("'+d.time+'")');
            var t = document.createTextNode(d.time);
            button.appendChild(t);
            $("#timeline").append(button);
            years.push(d.time);
        }
    })

    //create circles for the first year 
    svg.selectAll("circles")
        .data(dataset.filter(function(d) { return d.time == d3.min(years);}, function(d) { return d.name; }))
        .enter()
        .append("circle")
        //.filter(function(d){ return d.time == d3.min(years); })
        .attr("cx", function (d) { return d.xAxis *10; })
        .attr("cy", function (d) { return d.yAxis; })
        .style("fill", function(d) { return d.color; })
        .transition()
        .duration(800)
        .attr("r", function(d) { return d.radius});
});

我的更新功能:

function update(year){
    var circle = svg.selectAll("circles")
                .data(data.filter(function(d){return d.time == year;}), function(d) { return d.name; });

    //update
    circle.attr("class", "update")
        .filter(function(d){ return d.time == year; })
        .transition()
        .duration(800)
        .attr("cx", function (d) { return d.xAxis *10; })
        .attr("cy", function (d) { return d.yAxis; })
        .attr("r", function(d) { return d.radius});


    //enter
    circle.enter().append("circle")
            .filter(function(d){ return d.time == year; })
            .attr("cx", function (d) { return d.xAxis *10; })
            .attr("cy", function (d) { return d.yAxis; })
            .style("fill", function(d) { return d.color; })
            .attr("r", function(d) { return d.radius});

    //exit
    circle.exit()
        .remove();
}

有人能指出我正确的方向吗?感谢。

1 个答案:

答案 0 :(得分:0)

svg.selectAll("circles")无效,应该成为svg.selectAll("circle")(单圈“圈”)。

正如您目前使用"circles"一样,它产生一个空选择,因此d3假设您的所有数据都绑定到不存在的圈子,因此.enter()选择始终为满(相反)而不是只在第一次渲染时才满。)

接下来,在标有//update标记的部分中,您不需要进行任何过滤。您对过滤后的数组所做的.data()绑定应该为您解决此问题。

此外,标有//create circles for the first year的部分是不必要的,可能应删除以消除副作用错误。 update()函数,假设它正常工作,应该为你处理。