Удалить круг при нажатии на него - Javascript - PullRequest
0 голосов
/ 27 ноября 2018

Я бы хотел иметь возможность щелкнуть точку и заставить ее уйти, давая также значение R (когда переключатель удаления установлен).Иначе, если это часть, которая должна быть изменена.В настоящее время он удаляет последнее созданное значение, но не то, на которое я нажимаю.Кроме того, круг не удаляется, все есть (вам не нужно читать весь код, но его запуск может быть полезным для понимания).

ПРИМЕЧАНИЕ. Важно, что щелкается круг, а не координата, поскольку он слишком мал.Также важно, чтобы круг исчез, а не только значение в наборе данных.

У меня есть следующий код:

// Width and height of svg
var w = 600;
var h = 400;
var padding = 15;

var xmin = -50;
var xmax = 50;
var ymin = -30;
var ymax = 30;

var button1 = document.getElementById("button1");
var button2 = document.getElementById("button2");

var dataset = [];

var xScale = d3.scaleLinear()
  .domain([xmin, xmax])
  .range([padding, w - padding]);

var yScale = d3.scaleLinear()
  .domain([ymax, ymin])
  .range([padding, h - padding]);

var svg = d3.select("body").append("svg")
  .attr("width", w)
  .attr("height", h);

svg.append("g")
  .attr("transform", "translate(0," + h / 2 + ")")
  .call(d3.axisBottom()
    .scale(xScale)
    .tickValues([-40, -20, 20, 40]));

svg.append("g")
  .attr("transform", "translate(" + w / 2 + ",0)")
  .call(d3.axisLeft()
    .scale(yScale)
    .tickValues([30, 20, 10, -10, -20, -30]));

svg.on("click", function() {
  if (button1.checked) {
    var coords = d3.mouse(this);
    console.log(coords);
    
    dataset.push({
      x: coords[0],
      y: coords[1]
    });
    
    svg.append("circle")
      .attr("cx", coords[0])
      .attr("cy", coords[1])
      .attr("r", 4)
      .attr("fill", 'red');

    d3.select("#correlation")
      .text(correlation(dataset));
  } else if (button2.checked) {
    var coords = d3.mouse(this);
    console.log(coords);
    
    var index = dataset.indexOf(coords);
    
    if (index > -1) {
      dataset.splice(index, 1);
    }
    
    d3.select("#correlation")
      .text(correlation(dataset));
  }
});

function correlation(dataset) {
  if (dataset.length < 2) {
    return "We need at least two points.";
  } else {
    var top = 0;
    var bottom1 = 0;
    var bottom2 = 0;
    
    var meanx = d3.mean(dataset, function(d) {
      return xScale.invert(d.x);
    });
    
    var meany = d3.mean(dataset, function(d) {
      return yScale.invert(d.y);
    });
    
    for (i = 0; i < dataset.length; i++) {
      var x = xScale.invert(dataset[i].x);
      var y = yScale.invert(dataset[i].y);
      top += (x - meanx) * (y - meany);
      bottom1 += Math.pow(x - meanx, 2);
      bottom2 += Math.pow(y - meany, 2);
    }
    
    return "r: " + (top / (Math.sqrt(bottom1) * Math.sqrt(bottom2))).toFixed(2);
  }
}
<script src="https://d3js.org/d3.v4.min.js"></script>

<div style="width: 600px">
  <form>
    <input type="radio" name="radionbutton" value="1" id="button1">Add points</input>
    <input type="radio" name="radionbutton" value="2" id="button2">Remove points</input>
  </form>

  <h3 id="correlation">Two points are needed to calculate r.</h3>
</div>

1 Ответ

0 голосов
/ 27 ноября 2018

Проблема здесь

else if (button2.checked) {
  var coords = d3.mouse(this);
  var index = dataset.indexOf(coords);
  if (index > -1) {
    dataset.splice(index, 1);
  }
  d3.select("#correlation").text(correlation(dataset));
}

coords в вашем случае это массив из 2 элементов, x и y, он выглядит так [200, 50], в то время как ваш dataset является массивом объектовэто выглядит так [{x: 200, y: 50}], поэтому var index = dataset.indexOf(coords);, очевидно, не будет работать, так как вы ищете массив внутри массива объектов.

Вам нужно сделать что-то вроде этого:

else if (button2.checked)   {
  var coords = d3.mouse(this);
  var index = dataset.indexOf(coords);

  var index = dataset.findIndex(function(element) {
    return element.x === coords[0] && element.y === coords[1];
  });
  console.log('index', index);

  if (index > -1) {
    dataset.splice(index, 1);
  }
  d3.select("#correlation").text(correlation(dataset));
}

Будьте осторожны, потому что ваш y очень точный (он выглядит как '50 .2455'), что означает, что вы должны щелкнуть этот кружок в самом центре, чтобы вызвать его.Может быть, вы можете немного улучшить это.

ОБНОВЛЕНИЕ

Лучшим способом было бы инициировать событие всякий раз, когда вы нажимаете на область точки.Таким образом, поскольку точка равна 8px x 8px, вы можете добавить и вычесть 4px x 2 по обеим осям.Таким образом, удаление будет запускаться независимо от того, на какой части точки вы щелкнете.

else if (button2.checked)   {
  var coords = d3.mouse(this);
  var index = dataset.indexOf(coords);
  console.log(coords);
  console.log(dataset);

  var index = dataset.findIndex(function(element) {
    return element.x >= coords[0] - 4 && element.x <= coords[0] + 4 && element.y >= coords[1] - 4 && element.y <= coords[1] + 4;
  });
  console.log('index', index);

  if (index > -1) {
    dataset.splice(index, 1);
  }
  d3.select("#correlation").text(correlation(dataset));
  }
})

ОБНОВЛЕНИЕ

Это включает удаление точки из вида.

else if (button2.checked) {
  var coords = d3.mouse(this);
  var elX = null;
  var elY = null;

  var index = dataset.findIndex(function (element) {
    if (element.x >= coords[0] - 4 && element.x <= coords[0] + 4 && element.y >= coords[1] - 4 && element.y <= coords[1] + 4) {
      elX = element.x;
      elY = element.y;
    }
    return element.x >= coords[0] - 4 && element.x <= coords[0] + 4 && element.y >= coords[1] - 4 && element.y <= coords[1] + 4;
  });

  if (index > -1) {
    dataset.splice(index, 1);
    var d = document.querySelector('[cx="' + elX + '"][cy="' + elY + '"]');
    d.parentNode.removeChild(d);
  }
  d3.select("#correlation").text(correlation(dataset));
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...