d3.js:点击mouseout的等价物

时间:2014-07-11 18:44:57

标签: javascript d3.js

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

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

我对阅读许多例子的选择有一定的了解,但似乎无法弄清楚我应该采取什么方法来实现这一目标。

3 个答案:

答案 0 :(得分: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');
    });
  });

最后,您可以通过点击处理程序调用调度函数:

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);
});

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

这是一个演示JSBin

<强> - 编辑 -

我刚刚意识到,既然您正在尝试模仿鼠标输出,那么您可能不想要多选。您只需稍微更改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);
  });

这里有更新的JSBin

答案 1 :(得分:0)

在SVG上添加单击处理程序。在该点击处理程序中,首先取消选择所有圈子。然后,通过d3.event检查事件目标;如果是圆形,请选择它。伪代码描述:

svg.on('click', function() {
  circles.classed('selected', false);
  var target = /* get event target */;
  if (/* target is circle */) {
    target.classed('selected', true);
  }
});

答案 2 :(得分:0)

Jshanley的答案很棒,在大多数情况下可能更好,但我最后修改了一下:

svg.selectAll("dot").data(datasource).enter()  //you probably have your own thing here
    .on("mousedown", function(d) {  
        d3.selectAll("circle")    //this selects all of the elements you want to deselect by html tag (here its "circle")
        .style("fill", "black");  //default color of unselected elements, here its black
        d3.select(this)   //select the element that's just been clicked
        .style("fill", "orange");   //orange is the color of currently selected element
    });

只要在所选元素的样式之前应用所有元素的默认样式,此方法就可以正常工作。