I have a svg, and many gs in this svg.
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);
}
And I create a brush for each g:
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
})
);
}
The codes above cause a error because:
Uncaught RangeError: Maximum call stack size exceeded
How can I do this in other way?\
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>
<iframe name="sif1" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>
CodePudding user response:
brush
and start
are two different events, and there will never be a brush
that is not preceded by a start
, so you can omit the brush
here. That way, the code is not constantly triggering itself and the infinite loop recursion is avoided:
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>
<iframe name="sif2" sandbox="allow-forms allow-modals allow-scripts" frameborder="0"></iframe>