d3.js尝试对数据进行动画处理,但更改后的数据始终被视为新数据 [英] d3.js trying to animate data, but changed data always treated as new

查看:129
本文介绍了d3.js尝试对数据进行动画处理,但更改后的数据始终被视为新数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有json数据:一个框架数组,每个框架是10个节点的数组,每个节点都是一个字典,其中包含节点ID和x,y坐标. 我想创建一个d3动画,该动画在每个帧中的节点位置之间转换.

I have json data: an array of frames, each frame is an array of 10 nodes, and each node is a dictionary with the node id and x,y coordinates. I want to create a d3 animation that transitions between the positions of the node in each frame.

我正在使用setInterval(...)设置到下一组节点位置的过渡.但是,通过过渡会添加一堆新节点,而不是更新现有节点. 我在按键功能上有问题吗?

I am using setInterval(...) to set up the transitions to the next set of node positions. However, a bunch of new nodes are added instead of the existing nodes updating by going through the transition. Am I doing something wrong with the key function, or something else?

下面是json的示例:

Here's a sample of what the json looks like:

[[{"y": "0.898287995669", "x": "0.824201870934", "v": "0"}, {"y": "0.738482578278", "x": "0.645352934631", "v": "1"}, {"y": "0.12255740116", "x": "0.113578656145", "v": "2"}, {"y": "0.603047665154", "x": "0.609252770235", "v": "3"}, {"y": "0.497780597993", "x": "0.490370637301", "v": "4"}, {"y": "0.450309984776", "x": "0.428403273731", "v": "5"}, {"y": "0.512235180495", "x": "0.552584811488", "v": "6"}, {"y": "0.808721117001", "x": "0.829379563316", "v": "7"}, {"y": "0.771161177414", "x": "0.378854605349", "v": "8"}, {"y": "0.48703522369", "x": "0.162086851046", "v": "9"}], [{"y": "0.848393476015", "x": "0.0502693724025", "v": "0"}, {"y": "0.220251557696", "x": "0.653522019136", "v": "1"}, {"y": "0.0885518976544", "x": "0.17830262921", "v": "2"}, {"y": "0.179368661434", "x": "0.597837803239", "v": "3"}, {"y": "0.0333228956342", "x": "0.985417214534", "v": "4"}, {"y": "0.502384226146", "x": "0.668414759643", "v": "5"}, {"y": "0.242769234767", "x": "0.827774288391", "v": "6"}, {"y": "0.227109062114", "x": "0.352454692633", "v": "7"}, {"y": "0.830790971204", "x": "0.57313727618", "v": "8"}, {"y": "0.854927945281", "x": "0.0879122992914", "v": "9"}], ... ]

这是我当前的代码:

var width = 960,
    height = 500;
var padding = 10;

// inverted because of svg inverted y axis
var yscale = d3.scale.linear().domain([1,0]).range([padding, height - padding]);
var xscale = d3.scale.linear().domain([0,1]).range([padding, width - padding]);


var color = d3.scale.category20();

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height);

d3.json("out.json", function(error, json) {
  if (error) return console.warn(error);
  var graphFrames = json;
  startDrawing(graphFrames);
});


function drawFrame(graphFrame) {
    // DATA JOIN
    // Join new data with old elements, if any.
    var nodes = svg.selectAll("node")
        .data(graphFrame, function(d){ return d.v; });


    // UPDATE
    // Update old elements as needed.
    nodes.transition()
        .duration(750)
        .attr("cx", function(d) { return xscale(d.x); })
        .attr("cy", function(d) { return yscale(d.y); });


    // ENTER
    // Create new elements as needed.
    nodes.enter().append("circle")
        .attr("class", "node")
        .attr("r", 5)
        .attr("cx", function(d) { return xscale(d.x); })
        .attr("cy", function(d) { return yscale(d.y); })
        .style("fill", function(d, i){ return color(d.v % 20); });

    // EXIT
    // Remove old elements as needed.
    //nodes.exit().remove();
}


var nextFrameIdx = 1;
function startDrawing(graphFrames){
    // The initial display.
    drawFrame(graphFrames[0]);

    // Draw the next set of node coordinates at each interval
    setInterval(function() {
        drawFrame(graphFrames[nextFrameIdx]);
        nextFrameIdx = (nextFrameIdx + 1) % graphFrames.length;
    }, 1500);

}

推荐答案

您非常亲密.只需确保选择已创建的元素(.attr("class", "node");).所以:

You were very close. Just make sure you select the elements you have created (.attr("class", "node");). So:

var nodes = svg.selectAll(".node")
    .data(graphFrame);

您正在选择不存在的"node",因此始终设置回车选择.最好只让数据绑定基于索引(默认值),因为您基本上在选择中移动了相同的项目(=相同的索引).

You were selecting on "node" which does not exist and so the enter selection was always set. And it is fine to just let the data bind be based on the index, the default, since you are basically moving the same items (=same index) in the selection.

这是一个完整的 PLUNK .

这篇关于d3.js尝试对数据进行动画处理,但更改后的数据始终被视为新数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆