Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/apache-flex/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 将事件侦听器添加到d3笔刷_Javascript_D3.js - Fatal编程技术网

Javascript 将事件侦听器添加到d3笔刷

Javascript 将事件侦听器添加到d3笔刷,javascript,d3.js,Javascript,D3.js,我试图弄清楚如何使d3笔刷创建的矩形(特别是事件矩形)响应单击事件。最后,我希望单击这个对象就可以打开一个菜单,但是我似乎无法让rect元素捕捉到事件 我尝试了以下代码: var selector = d3.svg.brush(); var x = d3.scale.linear() .range([0,500]) .domain([0,500]); var y = d3.scale.linear() .range([0,500]) .domain([0,50

我试图弄清楚如何使d3笔刷创建的矩形(特别是事件矩形)响应单击事件。最后,我希望单击这个对象就可以打开一个菜单,但是我似乎无法让rect元素捕捉到事件

我尝试了以下代码:

var selector = d3.svg.brush();

var x = d3.scale.linear()
    .range([0,500])
    .domain([0,500]);

var y = d3.scale.linear()
    .range([0,500])
    .domain([0,500]);

d3.select('#myDiv')
    .append('svg')
    .attr('id','mySVG')
    .attr('height',500)
    .attr('width',500)
    .call(selector.x(x).y(y).on('brushend',bindSelect))

function bindSelect(){
    d3.select('#mySVG rect.extent')
        .on('click',function(){alert('hi mom!')})
}
bindSelect
似乎启动得很好,并成功地选择了
.extent
矩形,但单击该矩形时没有收到任何响应

var extent = selector.extent();

function bindSelect(){
  if(!selector.empty() && !(extent < selector.extent() || extent > selector.extent())) {
    console.log("foo");
  }
  extent = selector.extent();
}
问题似乎是d3在单击矩形时触发了一个
brushend
事件,我猜它会在某个地方停止事件传播

有人知道怎么避开这件事吗?我唯一的想法是在
brushend
事件的extents rect之上创建另一个rect,然后使用该rect处理单击行为,但这似乎是一种混乱的操作方式


另外,

获取您想要的事件可能有点麻烦,需要更改D3源代码。但是,您可以将
brushend
事件与为笔刷提供的方法一起使用,以确定是否有人单击了笔刷矩形

var extent = selector.extent();

function bindSelect(){
  if(!selector.empty() && !(extent < selector.extent() || extent > selector.extent())) {
    console.log("foo");
  }
  extent = selector.extent();
}
var-extent=selector.extent();
函数bindSelect(){
如果(!selector.empty()&&&!(区段selector.extent()){
控制台日志(“foo”);
}
extent=selector.extent();
}

其思想是,如果选择内容不是空的,并且所选范围与上次“刷边”事件中的范围相同,则用户单击选择内容而不是对其进行操作。

这是Lars答案的一个稍微改进版本,用于处理两种边缘情况:

  • 如果拖动笔刷并将其返回到精确的原始位置,这将触发事件
  • 如果将笔刷拖过容器的末端,则当光标移动时,笔刷不会移动,也会触发事件
  • 首先,按如下方式设置笔刷:

    selector.x(x).y(y).on('brushstart', saveCursorPos)
                      .on('brushend',   checkIfMoved))
    
    那么

    var clickPos = [-1,-1];
    
    function saveCursorPos() {
        var e = d3.event.sourceEvent;
        clickPos = [e.clientX,e.clientY];
    }
    
    function checkIfMoved() {
        var e = d3.event.sourceEvent;
        if(!selector.empty() && clickPos[0] === e.clientX && clickPos[1] === e.clientY) {
            alert("foo");
        }
    }
    

    这样做的目的是在开始拖动时保存鼠标位置,而不是笔刷范围,并在释放按钮时检查该位置是否已更改

    这里需要注意两件事:1。如果拖动笔刷并将其返回到精确的原始位置,这将触发事件。2.如果将笔刷拖过容器的末端,则当光标移动时,笔刷不会移动,也会触发事件。