block by davo b3b0fd711c6610148475

b3b0fd711c6610148475

Full Screen

Shows multiple overlaid Voronoi diagrams, given multiple point sets.

index.html

<!doctype html>
<meta charset="utf-8">
<style>
  path {
    fill-opacity: .5;
    stroke-width: 2;
  }
  form {
    display: inline-block;
    margin-right: 30px;
  }
  input {
    width: 150px;
    vertical-align: middle;
  }
  output {
    display:inline-block;
    width: 3em;
  }
</style>
<body>
<div>
  <form oninput="displayNumSets.value=numSets.value">
    <label>Number of Sets:
      <input type="range" id="numSets" min="1" max="10" value="4" />
      <output id="displayNumSets">4</output>
    </label>
  </form>
  <form oninput="displayNumPts.value=numPts.value">
    <label>Number of Points Per Set:
      <input type="range" id="numPts" min="1" max="50" value="8" />
      <output id="displayNumPts">8</output>
    </label>
  </form>
<button id="submit">Update</button>
</div>

</body>
<script src="//d3js.org/d3.v3.js"></script>
<script>
// initialize chart area
var chart = d3.select('body').append('svg')
    .attr('class', 'chart')
    .attr('width', 960)
    .attr('height', 450);

var x = d3.scale.linear()
    .domain([0, 1])
    .range([50, 910]);

var y = d3.scale.linear()
    .domain([0, 1])
    .range([50, 400]);

var color = d3.scale.ordinal().range(['red', 'blue', 'lime', 'cyan',
  'purple', 'orange', 'brown', 'forestgreen', 'black', 'gold']);

d3.selection.prototype.moveToFront = function() {
  return this.each(function(){
    this.parentNode.appendChild(this);
  });
};

function update() {
  var num_sets = d3.select('#numSets').property('value') || 4,
      num_pts = d3.select('#numPts').property('value') || 8;
  var dataset = [];
  for (var i = 0; i < num_sets; i++) {
    var set = [];
    for (var j=0; j < num_pts; j++) {
      var px = Math.random();
      var py = Math.random();
      set.push({x: px, y: py});
    }
    dataset.push(set);
  }

  var voronois = dataset.map(function(d, i) {
    var pts = d.map(function(pt) {console.log(pt); return [x(pt.x), y(pt.y)];});
    console.log(pts);
    return d3.geom.voronoi(pts);
  });

  chart.selectAll('path.voronoi').remove();
  var p = chart.selectAll('path.voronoi').data(voronois);

  p.enter().append('path')
      .style('stroke', function(d, i) {return color(i);})
      .style('opacity', 0.0)
      .style('fill', 'none')
      .attr('class', 'voronoi')
      .attr('d', function(d) { return "M" + d.map(function(pt) {return pt.join('L');}).join("M"); });

  p.transition().duration(800)
    .transition().duration(200)
      .style('opacity', 0.7);

  var groups = chart.selectAll('g').data(dataset);

  groups.enter().append('g');
  groups.exit().remove();
  groups.moveToFront();

  var c = groups.selectAll('circle').data(function(d) {return d;});

  c.enter().append('circle')
      .attr('r', 6)
      .attr('fill', function(d, i, j) {return color(j);})
      .style('opacity', 0.0);
  c.exit().remove();

  c.transition().duration(1000)
      .attr('cx', function(d) {return x(d.x);})
      .attr('cy', function(d) {return y(d.y);})
      .style('opacity', 1.0);
}
update();

d3.select('#submit').on('click', update);
d3.selectAll('form').on('change', update);

</script>