D3 JS создает полигон по щелчку

#javascript #d3.js

#javascript #d3.js

Вопрос:

Рассмотрим следующий код

 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";
}
  

Как я могу добавить новый полигон щелчком мыши и одновременно нарисовать центральную точку?

Ответ №1:

У вас хорошее начало. В дополнение к mousemove слушателю на svg вам также нужен click слушатель. При этом вы можете просто добавлять новую вершину каждый раз, когда пользователь нажимает. Я сделал это, добавив переменную в функцию перерисовки, чтобы различать перерисовки, вызванные щелчком мыши. Возможно, вы сможете найти более чистый способ сделать это, но, надеюсь, это поможет!

 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>  

Комментарии:

1. Извините, я вроде как новичок, и я допустил ошибку с вашим именем.

2. Нет проблем. Добро пожаловать в SO!