d3反向气泡和标签动画

时间:2016-09-18 01:10:42

标签: javascript animation d3.js

我希望为此图表添加动画效果。 http://jsfiddle.net/NYEaX/1554/

var invisiblebubble = mask.append("circle")
  .data(data);

invisiblebubble
  .attr("cx", 550)
  .attr("cy", 250)
  .transition()
  .duration(900)
  .attr("r", function(d) {
    return d.value;
  });

我已经为面具圈制作动画 - 希望为标签实施其他动画/建议。如果它们像饼图一样补间,在弧形中补间,淡入等等。

我确实在圆的半径上创建了一个过渡 - 看起来像是华纳兄弟的结局。

var invisiblebubble = mask.append("circle")
  .data(data);

invisiblebubble
  .attr("cx", 550)
  .attr("cy", 250)
  .transition()
  .duration(2000)
  .attr("r", 10)
  .transition()
  .duration(900)
  .attr("r", function(d) {
    return d.value;
  });

如何为标签/指针等其他功能设置动画

我已设法使用此代码改进反向气泡图。

我必须首先为圆圈设置一个固定大小,然后对其进行遮罩,然后为其设置动画 - 用于标签。

function maskMaker(el){

                var backcolor = $(el).data("color");
                var backopacity = $(el).data("opacity");

                var height = $(el).data("height");
                var width = $(el).data("width");

                var labelName = $(el).data("label-name");
                var bubbleValue = $(el).data("bubble-value");
                var displaceLeft = $(el).data("displace-left");
                var displaceTop = $(el).data("displace-top");

                var data = [{
                  "label": labelName,
                  "x": displaceLeft,
                  "y": displaceTop,
                  "value": bubbleValue
                }];

                console.log("MASK data", data);


                // Set the main elements for the series chart
                var svgroot = d3.select($(el)[0]).append("svg");

                // filters go in defs element
                var defs = svgroot.append("defs");

                var mask = defs.append("mask")
                             .attr("id", "myMask");

                mask.append("rect")
                  .attr("x", 0)
                  .attr("y", 0)
                  .attr("width", "100%")
                  .attr("height", "100%")
                  .style("fill", "white")
                  .style("opacity", backopacity);


              var invisiblebubble = mask.append("circle")
                .data(data);


              //create a fixed bubble first                  
                invisiblebubble
                  .attr("cx", "50%")
                  .attr("cy", "50%")
                  .attr("r", function(d) {
                    return d.value-20;
                  });            


               //now mask the fixed circle     
                var masker = defs.append(function() { 
                  return mask.node().cloneNode(true)
                })
                  .attr("id", "myMaskForPointer")
                  .select("rect")
                  .style("opacity", 0.8);


               //animate this circle
                invisiblebubble
                  .attr("cx", "50%")
                  .attr("cy", "50%")
                  .attr("r", 10)
                  .transition()
                  .duration(900)
                  .attr("r", function(d) {
                    return d.value;
                  });


               //apply the rest of the chart elements 
                var svg = svgroot
                  .attr("class", "series")
                  .attr("width", "1120px")
                  .attr("height", "500px")
                  .append("g")
                  .attr("transform", "translate(0,0)")


                var rect = svg
                  .append("rect")
                  .attr("x", 0)
                  .attr("y", 0)
                  .attr("width", "100%")
                  .attr("height", "100%")
                  .attr("mask", "url(#myMask)")
                  .style("fill", backcolor);


                    /*
                    //__labels 
                    var centrallabel = svgroot.append("g")
                      .attr("class", "centrallabel")
                      .data(data);

                centrallabel    
                      .append("text")
                      .attr("text-anchor", "middle")
                      .attr("x", 550)
                      .attr("y", 250 + 10)
                      .text(function(d) {
                        return "200";
                      })
                      */                    


                    function addLabel(){

                      //__labels 
                      var labels = svgroot.append("g")
                        .attr("class", "labels")

                      //__ enter
                      var labels = labels.selectAll("text")
                        .data(data);

                      labels.enter()
                        .append("text")
                        .attr("text-anchor", "middle")

                      //__ update
                      //labels

                        .attr("x", function(d) {
                          return d.x;
                        })
                        .attr("y", function(d) {
                          return d.y-10;
                        })
                        .text(function(d) {
                          return d.label;
                        })
                        .each(function(d) {
                          var bbox = this.getBBox();
                          d.sx = d.x - bbox.width / 2 - 2;
                          d.ox = d.x + bbox.width / 2 + 2;
                          d.sy = d.oy = d.y + 5;
                          d.cx = 550;
                          d.cy = 250;
                        })
                        .transition()
                        .duration(300)

                      labels
                        .transition()
                        .duration(300)

                      //__ exit
                      labels.exit().remove();
                      //__labels                     
                    }


                    function addPointer(){
                      //__pointers
                      var pointers = svgroot.append("g")
                        .attr("class", "pointers");


                      var dots = defs.append("marker")
                            .attr("id", "circ")
                            .attr("markerWidth", 6)
                            .attr("markerHeight", 6)
                            .attr("refX", 3)
                            .attr("refY", 3);                    


                      var pointers = pointers.selectAll("path.pointer")
                        .data(data);

                      //__ enter
                      pointers.enter()
                        .append("path")
                        .attr("class", "pointer")
                        .style("fill", "none")
                        .attr("marker-end", "url(#circ)")
                        .attr("mask", "url(#myMaskForPointer)")

                      //__ update
                      //pointers
                        .attr("d", function(d) {
                          if (d.cx > d.ox) {
                            return "M" + d.sx + "," + d.sy + "L" + d.ox + "," + d.oy + " " + d.cx + "," + d.cy;
                          } else {
                            return "M" + d.ox + "," + d.oy + "L" + d.sx + "," + d.sy + " " + d.cx + "," + d.cy;
                          }
                        })
                        .transition()
                        .duration(300)

                      pointers
                        .transition()
                        .duration(300)

                      //__ exit
                      pointers.exit().remove();
                      //__pointers 
                    }

                    //delay for the mask
                    setTimeout(function(){ 
                      addLabel();
                      addPointer(); 
                    }, 1000);  

              }

1 个答案:

答案 0 :(得分:0)

淡入可以实现如下:

centrallabel
  .append("text")
  .attr("text-anchor", "middle")
  .attr("x", 550)
  .style("opacity",0)
  .attr("y", 250 + 10)
  .text(function(d) {
    return "200";
  })
  .transition()
  .duration(2000)
   .style("opacity", 1)

就其他动画而言,您可以在屏幕外启动指针线,然后将其转换为其终点。或者从0开始,将其转换为完整大小。转换/翻译可能会有用 - 请参阅(https://bl.ocks.org/mbostock/1345853