我想将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.... */
})
答案 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。