Simeon Simeonov
Simeon Simeonov

Reputation: 51

D3 JS make polygon on click

Consider the following code

var width = 960,
    height = 500;

var vertices = d3.range(100).map(function(d) {
  return [Math.random() * width, Math.random() * height];
});

var voronoi = d3.geom.voronoi()
    .clipExtent([[0, 0], [width, height]]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .on("mousemove", function() { vertices[0] = d3.mouse(this); redraw(); });


var path = svg.append("g").selectAll("path");

svg.selectAll("circle")
    .data(vertices.slice(1))
  .enter().append("circle")
    .attr("transform", function(d) { return "translate(" + d + ")"; })
    .attr("r", 1.5);

redraw();

function redraw() {
  path = path
      .data(voronoi(vertices), polygon);

  path.exit().remove();

  path.enter().append("path")
      .attr("class", function(d, i) { return "q" + (i % 9) + "-9"; })
      .attr("d", polygon);

  path.order();
}

function polygon(d) {
  return "M" + d.join("L") + "Z";
}

How can I add a new Polygon with a CLICK & at the same time draw a center dot as well ?

Upvotes: 2

Views: 1060

Answers (1)

akosel
akosel

Reputation: 1183

You have a good start. In addition to the mousemove listener on the svg you also need a click listener. With this you can just add a new vertex each time the user clicks. I've done this by adding a variable to the redraw function to distinguish between redraws triggered by a click. You might be able to find a cleaner way to do this, but hopefully this helps!

var width = 960,
    height = 500;

var vertices = d3.range(100).map(function(d) {
  return [Math.random() * width, Math.random() * height];
});

var voronoi = d3.geom.voronoi()
    .clipExtent([[0, 0], [width, height]]);

var svg = d3.select("body").append("svg")
    .attr("width", width)
    .attr("height", height)
    .on("mousemove", function() { vertices[0] = d3.mouse(this); redraw(); })
    .on('click', function() { 
    	vertices.push(d3.mouse(this)); 
      redraw(true); 
     });


var path = svg.append("g").selectAll("path");

var circle = svg.selectAll("circle");

redraw();

function redraw(fromClick) {
  var data = voronoi(vertices);
  path = path
      .data(data, polygon);
  path.exit().remove();
  path.enter().append("path")
      .attr("class", function(d, i) { return "q" + (i % 9) + "-9"; })
      .attr("d", polygon);
  path.order();
  
  circle = circle.data(vertices)
  circle.attr("transform", function(d) { return "translate(" + d + ")"; })
  circle.enter().append("circle")
    .attr("transform", function(d) { return "translate(" + d + ")"; })
    .attr("r", 1.5)
    .attr('fill', fromClick ? 'white' : '')
  
  circle.exit().remove();
  
}
function polygon(d) {
  return d ? "M" + d.join("L") + "Z" : null;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>

Upvotes: 2

Related Questions