单击时删除圈子-Javascript

时间:2018-11-27 07:32:43

标签: javascript d3.js svg

我希望能够单击一个点并使其消失,同时也提供R值(当切换“删除”单选按钮时)。 else if是应更改的部分。当前它会删除最后一个创建的值,但不会删除我单击的那个值。此外,圆圈不会被删除,一切都将被删除(您无需阅读所有代码,但运行它可能有助于理解)。

注意:重要的是单击的是圆而不是坐标,因为它太小了。同样重要的是,圆消失了,而不仅仅是数据集上的值消失了。

我有以下代码:

// 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 :(得分:1)

问题在这里

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是x和y两个元素的数组,看起来像[200, 50],而您的dataset是一个对象数组,看起来像{{1 }},因此[{x: 200, y: 50}]显然不起作用,因为您要在对象数组中寻找数组。

您需要执行以下操作:

var index = dataset.indexOf(coords);

要小心,因为您的y非常精确(它看起来像“ 50.2455”),这意味着您必须单击中心的那个圆圈才能触发它。也许您可以对此加以改进。

更新

最好的方法是每当您单击点的区域时触发事件。因此,由于点是8px x 8px,因此您可以在两个轴上添加和减去4px x 2。这样,无论您单击点的哪一部分,删除都会触发。

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

更新

这包括从视图中删除点。

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