这个问题涉及到D3特定的函数,但不是D3特有的问题。我创建了两个带缩放功能的D3图表,并把它们连接在一起,让它们的缩放比例和位置保持一致,这样当一个图表被缩放时,另一个图表将自动缩放到相同的比例和位置。为了做到这一点,我在一个图表被缩放时触发了一个自定义事件,以便我可以自动调整另一个图表:
明显的问题是,调用
我想要实现的是一种检查
// Within the chart definition:
var svg = ...; // The chart body definition
var zoom = d3.behavior.zoom()
.on("zoom", function(e){
// do stuff...
$("#chart-div").trigger({
type: "my.zoom",
translate: d3.event.translate,
scale: d3.event.scale
});
});
svg.call(zoom);
然后我创建的方法允许我手动调整每个图表的缩放级别,在此过程中触发D3的zoom
事件:
var adjustZoom = function(t,s){
svg.transition().duration(500).call(zoom.scale(s).translate(t).event);
};
接下来,我会为每个图表添加事件监听器,这样当我与其中一个进行交互并导致其缩放级别发生变化时,其他图表会自动更新:
$("#chart-div1").on("my.zoom", function(e){
chart2.adjustZoom(e.translate, e.scale);
});
$("#chart-div2").on("my.zoom", function(e){
chart1.adjustZoom(e.translate, e.scale);
});
明显的问题是,调用
adjustZoom
方法会触发 D3 的 zoom
事件,因此在两个图表上附加事件监听器会创建循环事件,因为每个图表都试图无限调整另一个图表。1. chart1 [manual zoom] --> trigger d3.zoom --> triggers my.zoom
2. chart2 [my.zoom listener] --> trigger d3.zoom --> triggers my.zoom
3. chart1 [my.zoom listener] --> trigger d3.zoom --> triggers my.zoom
etc...
我想要实现的是一种检查
my.zoom
事件是否已经触发的方法,以便在决定触发另一个my.zoom
事件时,防止事件的循环触发(防止上述示例中的第3步),但我不知道如何去做。有没有一种方法让函数或事件意识到触发它的事件,并停止自身?
my.zoom
,并将自己作为源。我可能需要在每个事件处理程序中传递初始的source
值,以确保图表在响应其最初触发的事件链时不会触发事件。这可能有效,但不太优雅。 - woemler