清除d3.brush后如何调用函数?

时间:2018-10-11 10:26:35

标签: javascript d3.js

要对此进行详细说明,我们假设有一个典型的d3画笔用例,例如example here by Mike Bostock。 当我单击画笔外部的任何位置时,画笔都会被清除。因此,我希望在触发该事件时执行一个函数。 相关代码与Mike的示例非常相似。

2 个答案:

答案 0 :(得分:0)

在您提到的示例中,画笔被清除为"end"侦听器触发的默认行为。

惯用的D3解决方案正在设置"end"侦听器,以检查d3.event.selection是否为null

brush.on("end", function() {
    if(!d3.event.selection){
        //your function here;
    }
});

这里是使用Bostock代码的演示,请在笔刷外部单击并检查控制台消息:

<!DOCTYPE html>
<meta charset="utf-8">
<style>
  .axis--grid .domain {
    fill: #ddd;
    stroke: none;
  }

  .axis--x .domain,
  .axis--grid .tick line {
    stroke: #fff;
  }

  .axis--grid .tick--minor line {
    stroke-opacity: .5;
  }

</style>

<body>
  <script src="https://d3js.org/d3.v5.min.js"></script>
  <script>
    var margin = {
        top: 50,
        right: 40,
        bottom: 200,
        left: 40
      },
      width = 960 - margin.left - margin.right,
      height = 300 - margin.top - margin.bottom;

    var x = d3.scaleTime()
      .domain([new Date(2013, 7, 1), new Date(2013, 7, 15) - 1])
      .rangeRound([0, width]);

    var svg = d3.select("body").append("svg")
      .attr("width", width + margin.left + margin.right)
      .attr("height", height + margin.top + margin.bottom)
      .append("g")
      .attr("transform", "translate(" + margin.left + "," + margin.top + ")");

    svg.append("g")
      .attr("class", "axis axis--grid")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x)
        .ticks(d3.timeHour, 12)
        .tickSize(-height)
        .tickFormat(function() {
          return null;
        }))
      .selectAll(".tick")
      .classed("tick--minor", function(d) {
        return d.getHours();
      });

    svg.append("g")
      .attr("class", "axis axis--x")
      .attr("transform", "translate(0," + height + ")")
      .call(d3.axisBottom(x)
        .ticks(d3.timeDay)
        .tickPadding(0))
      .attr("text-anchor", null)
      .selectAll("text")
      .attr("x", 6);

    svg.append("g")
      .attr("class", "brush")
      .call(d3.brushX()
        .extent([
          [0, 0],
          [width, height]
        ])
        .on("brush", brushed)
        .on("end", function() {
          if (!d3.event.selection) console.log("you clicked ouside the brush")
        }));

    function brushed() {
      if (d3.event.sourceEvent.type === "brush") return;
      var d0 = d3.event.selection.map(x.invert),
        d1 = d0.map(d3.timeDay.round);

      // If empty when rounded, use floor instead.
      if (d1[0] >= d1[1]) {
        d1[0] = d3.timeDay.floor(d0[0]);
        d1[1] = d3.timeDay.offset(d1[0]);
      }

      d3.select(this).call(d3.event.target.move, d1.map(x));
    }

  </script>

答案 1 :(得分:-3)

使用您提到的示例,您必须在覆盖rect上添加点击处理程序,并跟踪是否有画笔设置

svg.append("g")
    .attr("class", "brush")
    .call(d3.brushX()
        .extent([[0, 0], [width, height]])
        .on("brush", brushed))
    .selectAll(".overlay")
        .on("mousedown touchstart", brushOverlay);

var brushSet = false;
function brushed() {
  if (d3.event.sourceEvent.type === "brush") return;
  var d0 = d3.event.selection.map(x.invert),
      d1 = d0.map(d3.timeDay.round);

  // If empty when rounded, use floor instead.
  if (d1[0] >= d1[1]) {
    d1[0] = d3.timeDay.floor(d0[0]);
    d1[1] = d3.timeDay.offset(d1[0]);
  }

  d3.select(this).call(d3.event.target.move, d1.map(x));
  brushSet = true;
}

function brushOverlay() {
  if (!brushSet) return; // create a new brush region
  console.log('brush Clear');
}

https://bl.ocks.org/mbostock/6498580改编