d3.js trying to animate data, but changed data always treated as new

感情迁移 提交于 2020-01-06 14:16:26

问题


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.

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?

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"}], ... ]

and here's what my current code is:

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);

}

回答1:


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);

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.

Here is a complete working PLUNK.



来源:https://stackoverflow.com/questions/23690793/d3-js-trying-to-animate-data-but-changed-data-always-treated-as-new

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!