首页 > 解决方案 > 单击它时删除圆圈 - Javascript

问题描述

我希望能够单击一个点并使其消失,同时给出 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>

标签: javascriptd3.jssvg

解决方案


问题就在这里

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

推荐阅读