concentric emanating circles d3

前端 未结 1 710
长发绾君心
长发绾君心 2021-01-23 09:00

I have an array of equally spaced values which I am using to draw concentric circles. I want to use an emanating effect, in essence, remove the outermost circle once its value e

1条回答
  •  失恋的感觉
    2021-01-23 09:39

    You could approach it with a remove().exit() and enter().append() selection for each ring - but essentially you always have the same number of rings on the screen. Why not just recycle the same elements? When the size hits a threshold, reset it to zero, or some other starting value?

    Something along the lines of:

    var scale = d3.scaleLinear()
      .range(["orange","steelblue","purple"])
      .domain([0,60]);
      
    var data = [0,10,20,30,40,50,60];
    
    var width = 200;
    var height = 200;
    
    var svg = d3.select("body")
      .append("svg")
      .attr("width",width)
      .attr("height",height);
      
    var circles = svg.selectAll("circle")
      .data(data)
      .enter()
      .append("circle")
      .attr("r",function(d) { return d; })
      .attr("transform","translate(80,80)")
      .attr("fill","none")
      .style("stroke-width","4")
      .style("stroke",function(d) { return scale(d) });
      
    function transition() {
      // Update data, max d is 60:
      data = data.map(function(d) { return d == 60 ? 0 : d + 10});
      
      var i = 0;
      // Grow circles
      circles
         .data(data)
         .filter(function(d) { return d > 0 })
         .transition()
         .ease(d3.easeLinear)
         .attr("r", function(d) { return d; })
         .style("stroke", function(d) { return scale(d) })
         .style("opacity",function(d) { return d == 60 ? 0 : 1 }) 
         .duration(1000)
         .on("end",function(){if(++i==circles.size()-1) { transition(); } });
        
         
      // Reset circles where r == 0
      circles
        .filter(function(d) { return d == 0 })
        .attr("r", 0)
        .style("opacity",1)
        .style("stroke",function(d) { return scale(d); });
         
        
    }
    
    transition();

    Note that .on("end",... triggers on each element's transition end - this is why I count to see if all elements are done transitioning before running the transition function again.

    0 讨论(0)
提交回复
热议问题