0

My objective is to take a set of points, and move them (.transition.duration()) a few times, in series-like fashion.

Example of code:

d3.csv("X.csv", function(csv) {

    // initialize circles at random positions
   svg.selectAll("circle")
                    .data(csv)
                    .enter()
                    .append("circle")
                        .attr("cx", function(d) {
                            return x(80*Math.random());
                        })  
                        .attr("cy", function(d) {
                            return y(500*Math.random());
                        })
                        .attr("r", function(d) {
                            return r(Math.sqrt(10*Math.random()));
                        })
                        .style("fill", function(d) {
                            return color(d.A);
                        })
                    .style("opacity", 1.0) 
                    .style("stroke-opacity", 1) 
                    .style("stroke-width", 3)
                    .style("stroke", function(d) {
                        return stroke(d.B) 
                    });

    // Move #1: moving the marks to their position
    svg.selectAll("circle")
        .transition().duration(2000)
        .attr("cx",function(d) {
            return x(+d.C);
        })
        .attr("cy",function(d) {
            return y(+d.D);
        })
        .attr("r",function(d) {
            return r(Math.sqrt(+d.E));
        })
        .style("opacity", 0.8);

    //Move #2: move again to highlight
    svg.selectAll("circle")
        .transition().duration(2000)
        .style("opacity", function(d) {
            if (d["A"] == "male") {
                return 0.1;
            } else if (d["A"] == "female") {
                return 0.8;
            }
        });
   }

Problem: Running as is, Move #1 is skipped over.

Failed Attempts: If I comment out Move #2 section, then Move #1 works. If I comment out Move #1 section, then Move #2 works.

Ideas considered: I have Googled .delay, setTimeout(), and other options with .exit() and further data bind steps, but I believe there should be something simpler that exists. I have also tried to follow this SO post, but have a hard time following the "General Update Pattern" examples of the first answer.

Question: How do I get Move #1 and Move #2 to work in succession (with possible further Moves #3, #4, etc.)?

ximiki
  • 435
  • 6
  • 17

1 Answers1

3

Excellent tutorial here

Idea is delay the second transition by the duration of first transition.

So if you have 3 transitions each of duration 1 sec then, delay the second by 1 sec and third by 2 sec, because we have to wait for both first and second transitions to complete. Hope you get the idea.

var canvas = d3.select('body')
      .append("svg")
      .attr("width",500)
      .attr("height",500);
  var addcircle = canvas.append("circle")
       .attr("cx",50)
       .attr("cy",50)
       .attr("r",25);  
  
  var circles = d3.select('circle');
  
  // first transition
  circles.transition().duration(1000)
    .attr("cx",250);
  
  // 2nd
  circles.transition().delay(1000)
    .duration(1000)
    .attr("cy",250)
  // 3rd
  circles.transition().delay(2000)
    .duration(1000)
    .attr("cx",50)
  // 4th
  circles.transition().delay(3000)
    .duration(1000)
    .attr("cy",50);
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
Umesh Maharshi
  • 1,571
  • 10
  • 12
  • This is exactly what I was looking for, and was able to implement the idea on my problem to get to the desired solution. Thank you for your time and effort! Hope this helps others in the future. – ximiki Jul 26 '16 at 19:53