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>
brush
和start
是两个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>
我有一个 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>
brush
和start
是两个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>