d3 js - 将气泡聚类到细分

时间:2016-08-27 00:42:48

标签: javascript d3.js

**** LATEST FIDDLE --- https://jsfiddle.net/tk5xog0g/8/

- 自定义图表的第二小提琴 - 随机将气泡放置在靠近区域的区域,但不能解释重叠或从中央图表区域掉落。 http://jsfiddle.net/NYEaX/1484/

我想结合一个doughtnut馅饼和一个气泡图来产生一个像这样的确切结果

enter image description here

我最接近的是 - 就在这里。

enter image description here

https://jsfiddle.net/tk5xog0g/10/

/* ------- 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 = bubbles.transition()
  .transition()
  .duration(250)
  .attr('transform', function(d) {
    return 'translate(' + d.x + ',' + d.y + ')';
  })
  .attr('r', function(d) {
    //console.log("dr", d.r)
    return d.r;
  })
  .ease('sine');

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

我还试图将气泡图聚类到至少总是将颜色组合在一起 - 但这仍然不符合所需的图表 - 需要将颜色气泡接近匹配的饼图段。

- 这是一个聚集的变种,但橙色气泡可能夹在中间,一旦我尝试将它与馅饼合并 - 将不相符。我曾考虑尝试添加电荷/重力以试图让气泡排斥。 https://jsfiddle.net/tk5xog0g/20/ enter image description here

https://bl.ocks.org/mbostock/7881887

var width = 960,
    height = 500,
    radius = Math.min(width, height) / 2;

var color = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

var arc = d3.svg.arc()
    .outerRadius(radius - 60)
    .innerRadius(radius - 70);

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

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");


  var data = [
    {
      "group": "<5",
      "value": 1000,
      "children": [
        {
          "group": "<5",     
          "label": "Mel",
          "value": 1000,
          "totalGroupValue": 1000
        }
      ]
    },
    {
      "group": "5-13",
      "value": 1000,
      "children": [
        {
          "group": "5-13",        
          "label": "Erica",
          "value": 1000,
          "totalGroupValue": 1000
        }
      ]
    },
    {
      "group": "14-17",
      "value": 2000,
      "children": [
        {
          "group": "14-17",
          "label": "Jessica",
          "value": 1500,
          "totalGroupValue": 2000  
        },
        {
          "group": "14-17",
          "label": "Jill",
          "value": 500,
          "totalGroupValue": 2000  
        }
      ]
    },
    {
      "group": "18-24",
      "value": 1300,
      "children": [
        {
          "group": "18-24",
          "label": "Jerry",
          "value": 500,          
          "totalGroupValue": 1300 
        },
        {
          "group": "18-24",
          "label": "Ben",
          "value": 500,
          "totalGroupValue": 1300  
        },
        {
          "group": "18-24",
          "label": "Billy",
          "value": 300,
          "totalGroupValue": 1300  
        }
      ]
    },
    {
      "group": "25-44",
      "value": 1000,
      "children": [
        {
          "group": "25-44",
          "label": "Kelly",
          "value": 1000,
          "totalGroupValue": 1000
        }
      ]
    }
  ];  


  var g = svg.selectAll(".arc")
      .data(pie(data))
    .enter().append("g")
      .attr("class", "arc");

  g.append("path")
      .attr("d", arc)
      .style("fill", function(d) {
        return color(d.data.group); 
      });

  arc
    .outerRadius(radius - 10)
    .innerRadius(0);
	  

//create zone regions
var zones = [];
g.append("circle")
  .attr("transform", function(d) {

    zones[d.data.group] = arc.centroid(d);
    //zones.push(obj);

    return "translate(" + arc.centroid(d) + ")"; 
  })
  .attr("r", "1px")
  .style("fill", function(d) { 
    return "black"//color(d.data.group); 
  });
//create zone regions


//custom bubble chart
function makeBubbles(transform, group, radius){
    g.append("circle")
    .attr("transform", function(d) {
      return "translate("+transform+")"; 
    })
    .attr("r", radius)
    .style("stroke", function(d) { 
      return "black";//color(group); 
    })
    .style("fill", function(d) { 
      return color(group); 
    });
}

//loop through data and for EACH children array paint dots.
$.each(data, function( index, value ) {

  $.each(value.children, function( i, v ) {
      var randomX = Math.floor(Math.random() * 101) - 50;
      var randomY = Math.floor(Math.random() * 101) - 50;      

      var zoneregion = zones[v.group];
      var transform = (zoneregion[0] - randomX)+","+(zoneregion[1]+randomY);
      var group = v.group;
      var radius = ((v.value/v.totalGroupValue)*100) *0.5;
      makeBubbles(transform, group, radius);

  });    
});    
//custom bubble chart    
   

function type(d) {
  d.value = +d.value;
  return d;
}
.arc text {
  font: 10px sans-serif;
  text-anchor: middle;
}

.arc path {
  stroke: #fff;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.1.0/jquery.min.js"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<body>

2 个答案:

答案 0 :(得分:1)

希望这有帮助。

var width = 960,
    height = 500,
    radius = Math.min(width, height) / 2;

var color = d3.scale.ordinal()
    .range(["#98abc5", "#8a89a6", "#7b6888", "#6b486b", "#a05d56", "#d0743c", "#ff8c00"]);

var arc = d3.svg.arc()
    .outerRadius(radius - 60)
    .innerRadius(radius - 70);

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

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
  .append("g")
    .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var data = [
	{"age":"<5", "population":"2704659"},
{"age":"5-13", "population":"4499890"},
{"age":"14-17", "population":"2159981"},
{"age":"18-24", "population":"3853788"},
{"age":"25-44", "population":"14106543"},
{"age":"45-64", "population":"8819342"},
{"age":"≥65", "population":"612463"}
];

  var g = svg.selectAll(".arc")
      .data(pie(data))
    .enter().append("g")
      .attr("class", "arc");

  g.append("path")
      .attr("d", arc)
      .style("fill", function(d) { return color(d.data.age); });

  arc
    .outerRadius(radius - 10)
    .innerRadius(0);
	  
  g.append("circle")
      .attr("transform", function(d) { return "translate(" + arc.centroid(d) + ")"; })
      .attr("r", "15px")
	  .style("fill", function(d) { return color(d.data.age); });

function type(d) {
  d.population = +d.population;
  return d;
}
.arc text {
  font: 10px sans-serif;
  text-anchor: middle;
}

.arc path {
  stroke: #fff;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

答案 1 :(得分:1)

enter image description here

最新小提琴。 http://jsfiddle.net/NYEaX/1505/

http://jsfiddle.net/NYEaX/1506/) - 重构

 1. -- how to animate the arcs
 2. -- how to animate the bubbles
 3. -- adding back the randomise button to test with 2 dummy data sets.

这是旧的馅饼动画,效果很好

                /* ------- 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 -------*/

//这是当前的饼形弧 - 但是当我尝试以相同的方式为饼图设置动画时 - 它会失败。

var g = svg.selectAll(".arc")
  .data(pie(data))
  .enter().append("g")
  .attr("class", "arc");

g.append("path")
  .attr("d", arc)
  .style("fill", function(d) {
    return color(d.data.label);
  });

arc
  .outerRadius(radius - 10)
  .innerRadius(0);