d3.js:单击mouseout的等效项

Nul*_*ame 3 javascript d3.js

我的意思是鼠标输出的点击相当于我想要一种方法来点击一个元素来改变一些属性,然后当我点击除该元素之外的任何东西时让它改回来.通过悬停切换此属性更改很容易,因为您基于鼠标悬停和鼠标移动更改了内容,但我不确定如何基于click事件执行相同操作.

所以我所拥有的是带有圆圈的svg元素,当它们被点击时会显示红色轮廓.我知道足以让一次只能选择一个圆圈,但是当我点击不是圆圈的svg的一部分时,我不知道如何取消选择所有节点.如果这还不够清楚,我可以创建一个jsfiddle来展示我到目前为止所拥有的东西.

我从阅读许多例子中获得了选择的工作知识,但似乎无法弄清楚我应该采取什么方法来实现这一目标.

jsh*_*ley 5

您可以使用d3.dispatch设置一些自定义事件处理.有时将不同的行为与其他布局代码分开有助于保持组织有序.

您可能希望一个功能取消高亮显示所有可点击的圆圈,另一个功能可以切换单个圆圈.然后,当单击svg时,您可以根据是否单击一个圆来决定是否取消全部高亮显示.

换一种说法...

单击圆圈时,切换它.

单击svg文档时,单击不在圆圈上,取消所有圆圈的亮度.

然后,您可以为这两个进程设置单独的调度事件.这很好,因为这些变成了可重用的行为.例如,如果您以后想要添加一个按钮以取消所有圆圈的高亮显示,或者想要在鼠标悬停时突出显示圆圈,则可以调用相同的调度功能.

var dispatch = d3.dispatch('unhighlightAll','toggleSingle')
  // remove the `highlighted` class on all circles
  .on('unhighlightAll', function() {
    d3.selectAll('.clickable-circle').classed('highlighted', false);
  })
  // toggle the `highlighted` class on element `el`
  .on('toggleSingle', function(el) {
    d3.select(el).classed('highlighted', function() {
      return !d3.select(el).classed('highlighted');
    });
  });
Run Code Online (Sandbox Code Playgroud)

最后,从您的点击处理程序调用调度函数:

svg.on('click', function() {
  // do nothing if a clickable circle is clicked
  if (d3.select(d3.event.target).classed('clickable-circle')) {
    return;
  } else {
  // otherwise unhighlight all circles
    dispatch.unhighlightAll();
  }
});

circles.on('click', function() {
  dispatch.toggleSingle(this);
});
Run Code Online (Sandbox Code Playgroud)

然后剩下的就是决定如何显示highlighted类,并在你的CSS中处理它.

这是一个演示JSBin

- 编辑 -

我刚刚意识到,既然你试图模仿mouseout,你可能不想要多选.你只需toggleSingle稍微改变一下这个功能:

dispatch.on('toggleSingle', function(el) {
    // store state of current element
    var highlighted = d3.select(el).classed('highlighted');
    // unhighlight all
    dispatch.unhighlightAll();
    // set opposite of stored state
    d3.select(el).classed('highlighted', !highlighted);
  });
Run Code Online (Sandbox Code Playgroud)

这是更新的JSBin.