d3.js 我有多个刷区。刷新区域时如何取消其他区域的刷区域?

d3.js I have multiple brush area. How can I cancel brush region in other area when I brush a new region?

我有一个 svg,这个 svg 中有很多 gs。

for (let j = 0; j < 3; j++) {
    let rx = 400 * j, ry = 100, rw = 300, rh = 300;
    let g = svg.append("g")
        .attr("x", rx).attr("y", ry)
        .attr("width", rw).attr("height", rh);
}

然后我为每个 g 创建一个 brush:

for (let j = 0; j < 3; j++) {
    let rx = 400 * j, ry = 100, rw = 300, rh = 300;
    let g = svg.append("g")
        .attr("x", rx).attr("y", ry)
        .attr("width", rw).attr("height", rh);

    g.call(d3.brush()
        .extent([[rx,ry], [rx+rw,ry+rh]])
        .on("start brush", function (e){
            svg.selectAll("g").call(d3.brush().clear);
            let extent = e.selection;
            //do something
            })
    );
}

以上代码会导致错误,因为:
Uncaught RangeError: Maximum call stack size exceeded
我怎样才能用其他方式做到这一点?\

let width = 2000;
let height = 1200;
let svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

for (let j = 0; j < 3; j++) {
  let rx = 400 * j,
    ry = 100,
    rw = 300,
    rh = 300;
  let g = svg.append("g")
    .attr("x", rx).attr("y", ry)
    .attr("width", rw).attr("height", rh);

  g.append("rect")
    .attr("x", rx).attr("y", ry)
    .attr("width", rw).attr("height", rh)
    .attr("fill", "white")
    .attr("stroke", "black");

  g.call(d3.brush()
    .extent([
      [rx, ry],
      [rx + rw, ry + rh]
    ])
    .on("start brush", function(e) {
      svg.selectAll("g").call(d3.brush().clear);
      let extent = e.selection;
    })
  );
}
<script src="https://d3js.org/d3.v7.min.js" charset="utf-8"></script>

brushstart是两个different events,永远不会有一个brush前面没有一个start,所以你可以这里省略 brush 。这样,代码就不会不断地触发自身,并且避免了无限循环递归:

let width = 2000;
let height = 1200;
let svg = d3.select("body")
  .append("svg")
  .attr("width", width)
  .attr("height", height);

for (let j = 0; j < 3; j++) {
  let rx = 400 * j,
    ry = 100,
    rw = 300,
    rh = 300;
  let g = svg.append("g")
    .attr("x", rx).attr("y", ry)
    .attr("width", rw).attr("height", rh);

  g.append("rect")
    .attr("x", rx).attr("y", ry)
    .attr("width", rw).attr("height", rh)
    .attr("fill", "white")
    .attr("stroke", "black");

  g.call(d3.brush()
    .extent([
      [rx, ry],
      [rx + rw, ry + rh]
    ])
    .on("start", function(e) {
      svg.selectAll("g").call(d3.brush().clear);
      let extent = e.selection;
    })
  );
}
<script src="https://d3js.org/d3.v7.min.js" charset="utf-8"></script>