【问题标题】:How to properly add and use D3 Events?如何正确添加和使用 D3 事件?
【发布时间】:2012-03-27 01:35:16
【问题描述】:

我无法理解使用 D3 事件和调度函数。我有一个我一直在研究的图表示例:“Vertical Bar Charts With Legends。”

绘制图表和图例很容易,但我想添加在将鼠标悬停在图表右侧的相关文本图例上时突出显示每个条形图的功能。

我已经阅读了所有的事件文档,甚至查看了一些示例,其中大部分都非常复杂,但我似乎遗漏了一些东西。有谁知道如何最好地完成文本图例鼠标悬停功能,即调度事件以自动更改相应垂直条的颜色?

【问题讨论】:

    标签: events d3.js dispatch


    【解决方案1】:

    这个问题类似于 d3-js Google Group 中的one you posted。在不复制我在那里写的内容的情况下,我会重申您可能不想要 d3.dispatch;用于自定义事件抽象(例如画笔和行为)。使用原生事件会更简单。

    如果您希望您的图例在鼠标悬停时更改相应栏的颜色,请将问题分解为以下步骤:

    1. 检测图例上的鼠标悬停。
    2. 选择相应的栏。
    3. 更改栏的填充颜色。

    首先,使用selection.on 监听图例元素上的“鼠标悬停”事件。当鼠标经过图例元素时,将调用您的侦听器函数,并使用两个参数调用:数据 (d) 和索引 (i)。您可以使用此信息通过d3.select 选择相应的栏。最后,使用selection.style 将“填充”样式更改为新颜色。

    如果您不确定如何在图例鼠标悬停时选择相应的栏,通常有几个选项。最直接的就是按索引选择,假设legend元素个数和rect元素个数一样,并且顺序相同。在这种情况下,如果局部变量 rect 包含 rect 元素,您可以说:

    function mouseover(d, i) {
      d3.select(rect[0][i]).style("fill", "red");
    }
    

    如果您不想依赖索引,另一种选择是根据相同数据扫描匹配条。这里使用selection.filter:

    function mouseover(d, i) {
      rect.filter(function(p) { return d === p; }).style("fill", "red");
    }
    

    另一个选项是给每个矩形一个唯一的 ID,然后按 id 选择。例如,在初始化时,您可以说:

    rect.attr("id", function(d, i) { return "rect-" + i; });
    

    然后,您可以在鼠标悬停时按 id 选择矩形:

    function mouseover(d, i) {
      d3.select("#rect-" + i).style("fill", "red");
    }
    

    上面的例子是人为的,因为我使用索引来生成 id 属性(在这种情况下,使用第一种按索引选择的技术更简单、更快捷)。一个更现实的例子是,如果您的数据具有 name 属性;然后您可以使用d.name 生成id 属性,同样按id 选择。如果您不想生成唯一 id,也可以按其他属性或类进行选择。

    【讨论】:

    • 嗨,迈克,感谢您在这方面提供的所有帮助。 D3 是一项很棒的技术,我很享受学习它的过程。 -- 弗兰克
    • FWIW 这个例子可以通过在有问题的 SVG 元素中添加一个 :hover CSS 规则来实现。
    • @HerbCaudill A :hover 规则在这种情况下过于局限:这个例子演示了如何修改除了被悬停的元素之外的元素(例如,图例到条形图)。 :hover 规则仅在您要修改的元素与悬停的元素相同时才有效(例如,图例)。在selecting and modifying related elements 上查看我的其他答案。
    【解决方案2】:

    Mike 的回答很棒。

    我用它来选择我正在绘制的网格中的一个单元格:

    .on('click', (d, i) ->
          console.log("X:" + d.x, "Y:" + d.y) #displays the cell x y location
          d3.select(this).style("fill", "red");
    

    因此,当我在其中输入数据时,我添加了事件侦听器并使用 d3.select(this)。

    在下面的上下文中查看代码:

     vis.selectAll("rect")
        .data(singleArray)
        .enter().append("svg:rect")
        .attr("stroke", "none")
        .attr("fill", (d) -> 
          if d.lifeForm
            return "green" 
          else
            return "white")
        .attr("x", (d) -> xs(d.x))
        .attr("y", (d) -> ys(d.y))
        .attr("width", cellWidth)
        .attr("height", cellHeight)
        .on('click', (d, i) ->
          console.log("X:" + d.x, "Y:" + d.y)
          d3.select(this).style("fill", "red");
          return
        ) 
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2016-10-04
      • 1970-01-01
      • 2017-07-17
      • 1970-01-01
      • 1970-01-01
      • 2019-04-25
      • 2019-10-16
      相关资源
      最近更新 更多