d3 - dougnut泡泡饼图

时间:2016-08-25 19:10:11

标签: javascript d3.js

enter image description here

我正在尝试创建合并的饼图/气泡图。

- 寻找起始气泡图表基础 - 也许这一个。 http://jsfiddle.net/xsafy/

^需要聚集这些气泡 - 每个切片可能有子气泡。

//气泡图表基础。 http://jsfiddle.net/NYEaX/1450/

enter image description here

(function() {

    var diameter = 250;

    var svg = d3.select('#graph').append('svg')
      .attr('width', diameter)
      .attr('height', diameter);

    var bubble = d3.layout.pack()
      .size([diameter, diameter])
      .value(function(d) {
        return d.size;
      })
      .padding(3);

    var color = d3.scale.ordinal()
      .domain(["Lorem ipsum", "dolor sit", "amet", "consectetur", "adipisicing"])
      .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56"]);


  function randomData() {

      var data1 = {
        "children": [
                {
                  name: "AA",
                  className: "aa",
                  size: 170
                },
                {
                  name: "BB",
                  className: "bb",
                  size: 393
                },
                {
                  name: "CC",
                  className: "cc",
                  size: 293
                },
                {
                  name: "DD",
                  className: "dd",
                  size: 89
                }
              ]
      };

      var data2 = {
        "children": [
                {
                  name: "AA",
                  className: "aa",
                  size: 120
                },
                {
                  name: "BB",
                  className: "bb",
                  size: 123
                },
                {
                  name: "CC",
                  className: "cc",
                  size: 193
                },
                {
                  name: "DD",
                  className: "dd",
                  size: 289
                }
              ]
      };



          var j = Math.floor((Math.random() * 2) + 1);
          console.log("j", j);

          if (j == 1) {
            return data1;
          } else {
            return data2;
          }

        }

  change(randomData());

  d3.select(".randomize")
    .on("click", function() {
      change(randomData());
    });

  function change(data) {
    console.log("data", data);

    // generate data with calculated layout values
    var nodes = bubble.nodes(data)
      .filter(function(d) {
         return !d.children;
      }); // filter out the outer bubble


    var vis = svg.selectAll('circle')
      .data(nodes);

    vis.enter()
      .insert("circle")
      .attr('transform', function(d) {
        return 'translate(' + d.x + ',' + d.y + ')';
      })
      .attr('r', function(d) {
        return d.r;
      })
      .style("fill", function(d) {
        return color(d.name);
      })
      .attr('class', function(d) {
        return d.className;
      });

    vis
      .transition().duration(1000)

    vis.exit()
      .remove();

  };

  })();

//圆环图表基础。 从这些例子中得出。 http://bl.ocks.org/dbuezas/9306799 https://bl.ocks.org/mbostock/1346410

enter image description here http://jsfiddle.net/NYEaX/1452/

  var svg = d3.select("#graph")
    .append("svg")
    .append("g")

  svg.append("g")
    .attr("class", "slices");
  svg.append("g")
    .attr("class", "labels");
  svg.append("g")
    .attr("class", "lines");

  var width = 560,
    height = 450,
    radius = Math.min(width, height) / 2;

  var pie = d3.layout.pie()
    .sort(null)
    .value(function(d) {
      return d.value;
    });

  var arc = d3.svg.arc()
    .outerRadius(radius * 0.85)
    .innerRadius(radius * 0.83);

  var outerArc = d3.svg.arc()
    .innerRadius(radius * 0.9)
    .outerRadius(radius * 0.9);

  svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

  var key = function(d) {
    return d.data.label;
  };

  var color = d3.scale.ordinal()
    .domain(["Lorem ipsum", "dolor sit", "amet", "consectetur", "adipisicing"])
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56"]);

  function randomData() {

    var data1 = [{
      "label": "AA",
      "value": 0.911035425558026
    }, {
      "label": "BB",
      "value": 0.08175111844879179
    }, {
      "label": "CC",
      "value": 0.25262439557273275
    }, {
      "label": "DD",
      "value": 0.8301366989535612
    }, {
      "label": "EE",
      "value": 0.0517762265780517
    }];

    var data2 = [{
      "label": "AA",
      "value": 0.243879179
    }, {
      "label": "BB",
      "value": 0.243879179
    }, {
      "label": "CC",
      "value": 0.2342439557273275
    }, {
      "label": "DD",
      "value": 0.2349535612
    }, {
      "label": "EE",
      "value": 0.2345780517
    }];

    var j = Math.floor((Math.random() * 2) + 1);

    if (j == 1) {
      return data1;
    } else {
      return data2;
    }

  }


  change(randomData());

  d3.select(".randomize")
    .on("click", function() {
      change(randomData());
    });


  function change(data) {

    /* ------- PIE SLICES -------*/
    var slice = svg.select(".slices").selectAll("path.slice")
      .data(pie(data), key);

    slice.enter()
      .insert("path")
      .style("fill", function(d) {
        return color(d.data.label);
      })
      .attr("class", "slice");

    slice
      .transition().duration(1000)
      .attrTween("d", function(d) {
        this._current = this._current || d;
        var interpolate = d3.interpolate(this._current, d);
        this._current = interpolate(0);
        return function(t) {
          return arc(interpolate(t));
        };
      })

    slice.exit()
      .remove();

  };

2 个答案:

答案 0 :(得分:0)

我到目前为止已经很接近了......我已经将这两个图表合并在一起了 - 虽然还有一个bug仍在尝试更新气泡 - 至少让它们进行缩放/变形/移动/动画。理想情况下,我希望他们能够贴近他们的小组......

这是小提琴。 https://jsfiddle.net/tk5xog0g/1/

enter image description here

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>doughpie</title>
        <link rel="stylesheet" href="css/generic.css">
        <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script>
        <script src="http://d3js.org/d3.v3.min.js"></script>
    </head>

    <body>
        <button class="randomize">randomize</button>
        <div data-role="doughpie" data-width="450" data-height="450" id="graph"></div>

        <script>
            //__invoke pie chart
            $('[data-role="doughpie"]').each(function(index) {
                createDoughnut(this);
            });


            function bubbledata(data){
                //loop through data -- and MERGE children
                var childs = [];
                $.each(data, function( index, value ) {
                    childs.push(value.children);                    
                });
                var merged = [].concat.apply([], childs);//flatterns multidimensional array

                return $.extend(true, {}, {"children": merged});// return deep clone
            }


            function createDoughnut(el){

                  var width = $(el).data("width"),
                    height = $(el).data("height"),
                    radius = Math.min(width, height) / 2;

                  var svg = d3.select($(el)[0])
                    .append("svg")
                    .attr("width", width)
                    .attr("height", height)



                  //_create doughpie shell
                      var doughpie = svg.append("g")
                            .attr("class", "doughpie");

                      doughpie.append("g")
                        .attr("class", "slices");
                      doughpie.append("g")
                        .attr("class", "labels");
                      doughpie.append("g")
                        .attr("class", "lines");


                      var pie = d3.layout.pie()
                        .sort(null)
                        .value(function(d) {
                          return d.value;
                        });

                      var arc = d3.svg.arc()
                        .outerRadius(radius * 0.85)
                        .innerRadius(radius * 0.83);

                      var outerArc = d3.svg.arc()
                        .innerRadius(radius * 0.9)
                        .outerRadius(radius * 0.9);

                      doughpie.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

                      var key = function(d) {
                        return d.data.label;
                      };

                      var color = d3.scale.ordinal()
                        .range(["#46a2de", "#7b3cce", "#31d99c", "#de5942", "#ffa618"]);
                  //_create doughpie shell


                  //_create bubble
                    var diameter = width/2;//take half/width

                    var bubs = svg.append("g")
                            .attr("class", "bubs");

                    bubs.attr("transform", "translate(" + diameter / 2 + "," + diameter / 2 + ")");

                    var bubble = d3.layout.pack()
                      .size([diameter, diameter])
                      .value(function(d) {
                        return d.size;
                      })
                      .padding(3);

                  //_create bubble



                  function randomData() {
                    var data1 = [{
                        "label": "AA",
                        "value": 0.911035425558026,
                        "children": [
                            {
                                name: "some text aa",
                                group: "AA",
                                size: 120
                            }
                        ]
                    }, {
                        "label": "BB",
                        "value": 0.08175111844879179,
                        "children": [
                            {
                                name: "some text bb",
                                group: "BB",
                                size: 123
                            }
                        ]
                    }, {
                        "label": "CC",
                        "value": 0.25262439557273275,
                        "children": [
                            {
                                name: "some text cc",
                                group: "CC",
                                size: 193
                            }
                        ]
                    }, {
                        "label": "DD",
                        "value": 0.8301366989535612,
                        "children": [
                            {
                                name: "some text dd",
                                group: "DD",
                                size: 29
                            },
                            {
                                name: "some text dd",
                                group: "DD",
                                size: 289
                            }
                        ]
                    }, {
                        "label": "EE",
                        "value": 0.0517762265780517,
                        "children": [
                            {
                                name: "some text ee",
                                group: "EE",
                                size: 389
                            },
                            {
                                name: "some text ee",
                                group: "EE",
                                size: 89
                            }
                        ]
                    }];

                    var data2 = [{
                        "label": "AA",
                        "value": 0.243879179,
                        "children": [
                            {
                                name: "some text aa",
                                group: "AA",
                                size: 120
                            }
                        ]
                    }, {
                        "label": "BB",
                        "value": 0.243879179,
                        "children": [
                            {
                                name: "some text bb",
                                group: "BB",
                                size: 123
                            }
                        ]
                    }, {
                        "label": "CC",
                        "value": 0.2342439557273275,
                        "children": [
                            {
                                name: "some text cc",
                                group: "CC",
                                size: 193
                            }
                        ]
                    }, {
                        "label": "DD",
                        "value": 0.2349535612,
                        "children": [
                            {
                                name: "some text dd",
                                group: "DD",
                                size: 29
                            },
                            {
                                name: "some text dd",
                                group: "DD",
                                size: 289
                            }
                        ]
                    }, {
                        "label": "EE",
                        "value": 0.2345780517,
                        "children": [
                            {
                                name: "some text ee",
                                group: "EE",
                                size: 389
                            },
                            {
                                name: "some text ee",
                                group: "EE",
                                size: 89
                            }
                        ]
                    }];

                    var j = Math.floor((Math.random() * 2) + 1);

                    if (j == 1) {
                      return data1;
                    } else {
                      return data2;
                    }
                  }


                  change(randomData());

                  d3.select(".randomize")
                    .on("click", function() {
                      change(randomData());
                    });

                  function change(data) {


                    /* ------- ANIMATE PIE SLICES -------*/
                    var slice = doughpie.select(".slices").selectAll("path.slice")
                      .data(pie(data), key);

                    slice.enter()
                      .insert("path")
                      .style("fill", function(d) {
                        return color(d.data.label);
                      })
                      .style("transform", function(d, i){
                        //return "translate(0, 0)";
                      })
                      .attr("class", "slice");

                    slice
                      .transition().duration(1000)
                      .attrTween("d", function(d) {
                        this._current = this._current || d;
                        var interpolate = d3.interpolate(this._current, d);
                        this._current = interpolate(0);
                        return function(t) {
                          return arc(interpolate(t));
                        };
                      })

                    slice.exit()
                      .remove();
                    /* ------- ANIMATE PIE SLICES -------*/


                    /* ------- ANIMATE BUBBLES -------*/


                       // generate data with calculated layout values

                        var data = bubbledata(data);

                        var nodes = bubble.nodes(data)
                          .filter(function(d) {
                             return !d.children;
                          }); // filter out the outer bubble


                        var bubbles = bubs.selectAll('circle')
                          .data(nodes);

                        bubbles.enter()
                          .insert("circle")
                          .attr('transform', function(d) {
                            return 'translate(' + d.x + ',' + d.y + ')';
                          })
                          .attr('r', function(d) {
                            return d.r;
                          })
                          .style("fill", function(d) {
                            return color(d.group);
                          });

                        bubbles
                          .transition().duration(1000)

                        bubbles.exit()
                          .remove();

                        /* ------- ANIMATE BUBBLES -------*/

                  };
            }
        </script>
    </body>
</html>

答案 1 :(得分:0)

我以为我会先尝试在弧线上绘制中点点 - 也许是从那些 - 开始得到一批区域坐标来掌控彩色气泡。

我一直在努力遵循这一点 - How to get coordinates of slices along the edge of a pie chart?

enter image description here

https://jsfiddle.net/tk5xog0g/28/

/*placing mid dots*/    
 var midDotsArrayCooridnates = [];

 slice
   .each(function(d) {
     x = 0 + (radius * 0.85) * Math.cos(d.startAngle);
     y = 0 + (radius * 0.85) * Math.sin(d.startAngle);

     var obj = {
       "x": x,
       "y": y
     }
     midDotsArrayCooridnates.push(obj);
   });

 $.each(midDotsArrayCooridnates, function(index, value) {
   var dot = doughpie.select(".slicedots").append('circle')
     .attr('cx', value.x)
     .attr('cy', value.y)
     .attr('r', 5)
     .style("fill", "red")
     .attr('class', "ccc")
 });

 /*placing mid dots*/