为什么D3的画笔开始事件会干扰以后的画笔事件?

时间:2016-10-05 18:34:36

标签: javascript d3.js

在下面的最小示例中,画笔用于选择圆圈(将它们指定为selected类),然后在最后清空。如果没有start事件,则每次刷子操作都会按预期增加选择。但是,除非按下ctrl键,否则添加brushstart()功能以清除每个画笔动作的开始。不知何故,它最终会消除稍后在brush事件期间发生的选择。您可以看到在刷牙过程中随着颜色的变化选择了圆圈,但是当释放鼠标时,它们都会被取消选中。

我该如何解决这个问题?让我感到困惑的是brushstart()如何取消brushmove()所做的选择。

'use strict'
var random = d3.randomUniform(0.1, 0.9),
  points = d3.range(50).map(function() {
    return [random(), random()]
  });

var svg = d3.select("svg"),
  width = +svg.attr("width"),
  height = +svg.attr("height");

var x = d3.scaleLinear()
  .domain([0, 1])
  .range([0, width]),
  y = d3.scaleLinear()
  .domain([0, 1])
  .range([height, 0]);

var brush = d3.brush()
  .on('start', brushstart)
  .on('brush', brushmove)
  .on("end", brushended);

var circles = svg.selectAll("circle")
  .data(points)
  .enter().append("circle")
  .attr("cx", function(d) {
    return x(d[0]);
  })
  .attr("cy", function(d) {
    return y(d[1]);
  })
  .attr("r", 2.5)
  .attr("fill", 'steelblue');

svg.append("g")
  .attr("class", "brush")
  .call(brush);

function brushstart() {
  // works as expected w/o the following line
  if (!d3.event.ctrlKey) {
    circles.classed('selected', false)
  }
}

function brushmove() {
  var s = d3.event.selection;
  if (s) {
    var newlySelected = circles.filter(function(d) {
      return s[0][0] <= x(d[0]) && x(d[0]) <= s[1][0] &&
        s[0][1] <= y(d[1]) && y(d[1]) <= s[1][1];
    });
    newlySelected.classed('selected', true);
  }
}

function brushended() {
  var s = d3.event.selection;
  if (s) {
    svg.select(".brush").call(brush.move, null);
  }
}
.selected {
  fill: crimson
}
<svg width="300" height="300"></svg>
<script src="https://d3js.org/d3.v4.min.js"></script>

1 个答案:

答案 0 :(得分:1)

从brushend调用

brushstart:

if (s) {
    svg.select(".brush").call(brush.move, null);
  }

也许你可以检查一下brushstart中的选择:

function brushstart() {
  // works as expected w/o the following line
  if (!d3.event.ctrlKey && d3.event.selection) {
    circles.classed('selected', false)
  }
}