title: Specifying a number of nodes in each cluster of clustered force layout in d3js
body: <p>I am trying to design an infographic using the Clustered Force Layout III example and I have it almost the way I want, but I need to specify a number of nodes per cluster. Cluster 1 - 10 nodes, Cluster 2 - 7 nodes, Cluster 3 - 11 nodes, Cluster 4 - 18 nodes, Cluster 5 - 16 nodes, Cluster 6 - 19 nodes, Cluster 7 - 42 nodes, Cluster 8 - 14 nodes. I have the correct total number of nodes and the correct total number of Clusters and I've made all the nodes the same size. Now I just need to push the circles around to represent by data. My code is below.</p>
  
  <pre><code>var width = 175,
      height = 175,
      padding = 1.5, // separation between same-color nodes
      clusterPadding = 6, // separation between different-color nodes
      maxRadius = 4;
  
  var n = 137, // total number of nodes
      m = 8; // number of distinct clusters
  
  var color = d3.scale.category10()
      .domain(d3.range(m));
  
  // The largest node for each cluster.
  var clusters = new Array(m);
  
  var nodes = d3.range(n).map(function() {
    var i = Math.floor(Math.random() * m),
        r = maxRadius,
        d = {
          cluster: i,
          radius: r,
          x: Math.cos(i / m * 2 * Math.PI) * 200 + width / 2 + Math.random(),
          y: Math.sin(i / m * 2 * Math.PI) * 200 + height / 2 + Math.random()
        };
    if (!clusters[i] || (r &gt; clusters[i].radius)) clusters[i] = d;
    return d;
  });
  
  var force = d3.layout.force()
      .nodes(nodes)
      .size([width, height])
      .gravity(.02)
      .charge(0)
      .on("tick", tick)
      .start();
  
  var svg = d3.select(".wpd3-1042-0").append("svg")
      .attr("width", width)
      .attr("height", height);
  
  var node = svg.selectAll("circle")
      .data(nodes)
    .enter().append("circle")
      .style("fill", function(d) { return color(d.cluster); })
      .call(force.drag);
  
  node.transition()
      .duration(750)
      .delay(function(d, i) { return i * 5; })
      .attrTween("r", function(d) {
        var i = d3.interpolate(0, d.radius);
        return function(t) { return d.radius = i(t); };
      });
  
  function tick(e) {
    node
        .each(cluster(10 * e.alpha * e.alpha))
        .each(collide(.5))
        .attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; });
  }
  
  // Move d to be adjacent to the cluster node.
  function cluster(alpha) {
    return function(d) {
      var cluster = clusters[d.cluster];
      if (cluster === d) return;
      var x = d.x - cluster.x,
          y = d.y - cluster.y,
          l = Math.sqrt(x * x + y * y),
          r = d.radius + cluster.radius;
      if (l != r) {
        l = (l - r) / l * alpha;
        d.x -= x *= l;
        d.y -= y *= l;
        cluster.x += x;
        cluster.y += y;
      }
    };
  }
  
  // Resolves collisions between d and all other circles.
  function collide(alpha) {
    var quadtree = d3.geom.quadtree(nodes);
    return function(d) {
      var r = d.radius + maxRadius + Math.max(padding, clusterPadding),
          nx1 = d.x - r,
          nx2 = d.x + r,
          ny1 = d.y - r,
          ny2 = d.y + r;
      quadtree.visit(function(quad, x1, y1, x2, y2) {
        if (quad.point &amp;&amp; (quad.point !== d)) {
          var x = d.x - quad.point.x,
              y = d.y - quad.point.y,
              l = Math.sqrt(x * x + y * y),
              r = d.radius + quad.point.radius + (d.cluster === quad.point.cluster ? padding : clusterPadding);
          if (l &lt; r) {
            l = (l - r) / l * alpha;
            d.x -= x *= l;
            d.y -= y *= l;
            quad.point.x += x;
            quad.point.y += y;
          }
        }
        return x1 &gt; nx2 || x2 &lt; nx1 || y1 &gt; ny2 || y2 &lt; ny1;
      });
    };
  }
  </code></pre>