D3.js删除了直接点击

时间:2017-09-24 14:23:47

标签: d3.js slider removeall

有很多help我已经能够点击矩形来移除它们。

但我怎样才能删除数据呢?目前存在一些奇怪的行为,例如先前删除的矩形重新出现以及创建与点击位于不同位置的矩形。我认为所有这些都是由于数据没有被删除这一事实造成的。

我想也许.exit()可能有用,但它没有。

这是一个工作片段。



<!DOCTYPE html>
<meta charset="utf-8">
<style>
  .active {
    stroke: #000;
    stroke-width: 2px;
  }
</style>
<svg width="960" height="500"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
  var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    radius = 32;

  var data = [{
      x: 100,
      y: 200
    },
    {
      x: 200,
      y: 300
    },
    {
      x: 300,
      y: 200
    },
    {
      x: 400,
      y: 300
    }
  ];

  var xScale = d3.scaleLinear()
    .domain([0, d3.max(data, function(d) {
      return d.x_pos
    })]).range([0, width]);

  svg.append("rect")
    .attr("x", 100)
    .attr("y", 250)
    .attr("rx", 2)
    .attr("ry", 2)
    .attr("height", 6)
    .attr("width", 800)
    .style("fill", "grey");

  svg.append("rect")
    .attr("x", 102)
    .attr("y", 252)
    .attr("rx", 2)
    .attr("ry", 2)
    .attr("height", 2)
    .attr("width", 796)
    .style("fill", "black");

  svg.selectAll("rect")
    .data(data)
    .enter().append("rect")
    .attr("x", function(d) {
      return d.x;
    })
    .attr("y", 200)
    .attr("height", 100)
    .attr("width", 15)
    .style("fill", "lightblue")
    .attr('id', function(d, i) {
      return 'rect_' + i;
    })
    .attr("rx", 6)
    .attr("ry", 6)
    .attr("stroke-width", 2)
    .attr("stroke", "black")
    .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended))
    .on("click", removeElement);

  svg.on("click", function() {
    var coords = d3.mouse(this);

    var newData = {
      x: d3.event.x,
      y: d3.event.y
    };

    data.push(newData);

    svg.selectAll("rect")
      .data(data)
      .enter()
      .append("rect")
      .attr("x", function(d) {
        return d.x;
      })
      .attr("y", 200)
      .attr("height", 100)
      .attr("width", 15)
      .style("fill", "steelblue")
      .attr('id', function(d, i) {
        return 'circle_' + i;
      })
      .attr("rx", 6)
      .attr("ry", 6)
      .attr("stroke-width", 2)
      .attr("stroke", "black")
      .call(d3.drag()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended))
      .on("click", removeElement);
  })

  function dragstarted(d) {
    d3.select(this).raise().classed("active", true);
  }

  function dragged(d) {
    d3.select(this)
      .attr("x", d.x = d3.event.x)
    // .attr("cy", d.y = d3.event.y);
  }

  function dragended(d) {
    d3.select(this)
      .classed("active", false);
  }

  function removeElement(d) {
    d3.event.stopPropagation();
    d3.select(this)
      .remove();
  }
</script>
&#13;
&#13;
&#13;

这个问题来自here

1 个答案:

答案 0 :(得分:2)

首先,您的数据数组有4个元素,但是您只附加了2个矩形。发生这种情况是因为您在该SVG中选择以前存在的矩形。因此,而不是:

svg.selectAll("rect")
    .data(data)
    .enter().append("rect")

应该是:

svg.selectAll(null)
    .data(data)
    .enter().append("rect")

回到你的问题:

D3有基于数据操作元素的方法,但不基于元素操纵数据。

因此,您必须自己更改数据阵列。例如,在removeElement内:

function removeElement(d) {
    data = data.filter(function(e){
        return e != d;
    });
};

以下是包含这些更改的代码:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  .active {
    stroke: #000;
    stroke-width: 2px;
  }
</style>
<svg width="960" height="500"></svg>
<script src="//d3js.org/d3.v4.min.js"></script>
<script>
  var svg = d3.select("svg"),
    width = +svg.attr("width"),
    height = +svg.attr("height"),
    radius = 32;

  var data = [{
      x: 100,
      y: 200
    },
    {
      x: 200,
      y: 300
    },
    {
      x: 300,
      y: 200
    },
    {
      x: 400,
      y: 300
    }
  ];

  var xScale = d3.scaleLinear()
    .domain([0, d3.max(data, function(d) {
      return d.x_pos
    })]).range([0, width]);

  svg.append("rect")
    .attr("x", 100)
    .attr("y", 250)
    .attr("rx", 2)
    .attr("ry", 2)
    .attr("height", 6)
    .attr("width", 800)
    .style("fill", "grey");

  svg.append("rect")
    .attr("x", 102)
    .attr("y", 252)
    .attr("rx", 2)
    .attr("ry", 2)
    .attr("height", 2)
    .attr("width", 796)
    .style("fill", "black");

  svg.selectAll(null)
    .data(data)
    .enter().append("rect")
    .attr("x", function(d) {
      return d.x;
    })
    .attr("y", 200)
    .attr("height", 100)
    .attr("width", 15)
    .style("fill", "lightblue")
    .attr('id', function(d, i) {
      return 'rect_' + i;
    })
    .attr("rx", 6)
    .attr("ry", 6)
    .attr("stroke-width", 2)
    .attr("stroke", "black")
    .call(d3.drag()
      .on("start", dragstarted)
      .on("drag", dragged)
      .on("end", dragended))
    .on("click", removeElement);

  svg.on("click", function() {
    var coords = d3.mouse(this);

    var newData = {
      x: d3.event.x,
      y: d3.event.y
    };

    data.push(newData);

    svg.selectAll("rect")
      .data(data)
      .enter()
      .append("rect")
      .attr("x", function(d) {
        return d.x;
      })
      .attr("y", 200)
      .attr("height", 100)
      .attr("width", 15)
      .style("fill", "steelblue")
      .attr('id', function(d, i) {
        return 'circle_' + i;
      })
      .attr("rx", 6)
      .attr("ry", 6)
      .attr("stroke-width", 2)
      .attr("stroke", "black")
      .call(d3.drag()
        .on("start", dragstarted)
        .on("drag", dragged)
        .on("end", dragended))
      .on("click", removeElement);
  })

  function dragstarted(d) {
    d3.select(this).raise().classed("active", true);
  }

  function dragged(d) {
    d3.select(this)
      .attr("x", d.x = d3.event.x)
    // .attr("cy", d.y = d3.event.y);
  }

  function dragended(d) {
    d3.select(this)
      .classed("active", false);
  }

  function removeElement(d) {
    d3.event.stopPropagation();
    data = data.filter(function(e){
    return e != d;
    });
    d3.select(this)
      .remove();
  }
</script>