将javascript对象与SVG元素相关联

时间:2014-05-26 11:49:57

标签: javascript html dom svg d3.js

目标

我想将d3.js创建的SVG元素与javascript对象相关联 - 这样当SVG元素在事件侦听器上可用时,我可以直接从它追溯到javascript对象。然而,这似乎在我的情况下没有解决,如下所述。

(动机)

我有很多SVG元素,每个元素逻辑上与一个包含与之相关的结构化数据的对象相关联。该数据确定当事件触发任何这些SVG元素时要执行的操作,并且每个SVG元素都有所不同

我的尝试

我只是将对象添加为SVG元素的新属性。我可以看到它被添加好了。 然后我使用d3' .on函数附加事件监听器。 我获得了我认为是d3.select(this)触发事件的SVG元素。实际上,我可以通过这种方式修改它的SVG属性,正如您在下面给出的代码集中悬停小矩形时所看到的那样。

问题

虽然我可以确认我的对象已添加到SVG对象中,但当我在事件处理程序中检索SVG元素时,它包含该对象引用的所有内容。

我将此问题减少到此codepen中的代码中 - 其中日志记录显示问题 - 将矩形悬停以检查它。

我做错了什么导致添加的对象引用无法使用? 我应该如何在SVG元素中使用对象引用正确完成,或者解决这个问题?

问题的代码说明:

rectangle = main.append('rect')
                           .style('fill', '#0000FF')   
                           .style('stroke-width', '0px')
                           .style('fill-opacity', '1')
                           .attr('height',30)
                           .attr('width',30)
                           .attr('id', '1')

rectangle.__test__ = 'test'



rectangle.on('mouseover', function(){
  console.dir(d3.select(this))
  /* __test__ is absent.... */
  })

1 个答案:

答案 0 :(得分:1)

您的示例代码无法正常工作的原因是因为rectangle 是对矩形元素的引用,它是对刚刚发生的d3选择的引用只包含一个元素。稍后创建相同元素的不同选择将不允许您访问初始选择的属性。

(为了理解它:把实际的SVGRectElement对象想象成一本图书馆书。那本书在你的背包里面(由rectangle引用的d3选项)。你创建了一些关于书(__test__),并将它们添加到你的背包中。然后你做其他的事情,后来有人拿出相同的图书馆书并把它放在不同的背包里。对于很多用途,效果是一样的:一个装有特定书籍的背包。如果你想阅读这本书或将它带到一个特定的课程,那么哪个背包里面的内容并不重要。但是,这个人不会去能够在他们的背包中神奇地找到你的笔记!)

如果你已经完成了

rectangle.node().__test__ = "test";  
//use .node() to extract the first element from the d3 selection
//and then assign a new property value to it

然后

console.dir(this.__test__);
//`this` directly references the rectangle element,  
// which has the test property added above

在事件处理程序中,它会工作。

但是通过使用d3数据函数将数据对象与每个元素相关联,然后直接将其作为事件处理函数的第一个参数进行访问,您可以更轻松地完成此操作。 花一些时间与the tutorials一起找出如何充分利用d3。