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