Как вызвать функцию, когда d3.brush очищен?

1

Чтобы уточнить это, скажем, у нас типичный случай использования кистей d3, что-то вроде примера здесь Майка Бостока. Кисть очищается, когда я нажимаю где-нибудь за пределами кисти. Поэтому я хочу выполнить функцию, когда это событие будет запущено. Соответствующий код довольно похож на пример Майка.

  • 0
    Пожалуйста, опубликуйте код, который вы уже пробовали, и прочитайте совет о том, как написать хороший вопрос на StackOverflow .
  • 1
    Несмотря на очевидные проблемы, это интересный вопрос, в отличие от скучных, которые заполняют этот тег d3.js. Я бы хотел, чтобы ФП приложил к этому некоторые усилия.
Теги:
d3.js

2 ответа

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="/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>
-4

Используя пример, который вы упомянули, вам нужно добавить обработчик кликов в оверлейный 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

Ещё вопросы

Сообщество Overcoder
Наверх
Меню