简体   繁体   English

将javascript对象与SVG元素相关联

[英]associating a javascript object to an SVG element

Goal 目标

I would like to associate a d3.js created SVG element to a javascript object - such that when the SVG element is made available on an event listener, I can trace back to the javascript object directly from it. 我想将d3.js创建的SVG元素与javascript对象相关联-这样,当在事件监听器上使SVG元素可用时,我可以直接从其追溯到javascript对象。 This however does not seem to work out in my case as explained below. 但是,在我的情况下,这似乎无法解决,如下所述。

(Motivation) (动机)

I have lots of SVG elements each logically associated to one object that contains structured data relevant to it. 我有很多SVG元素,每个元素在逻辑上与一个对象相关联,其中包含与其相关的结构化数据。 That data determines what to do when the event fires for any of those SVG elements, and is different for each of them 该数据决定了事件触发这些SVG元素中的任何元素时的处理方式,并且每个元素都不相同

My Attempt 我的尝试

I simply add the object as a new property for the SVG element. 我只是将对象添加为SVG元素的新属性。 I can see it's been added okay. 我可以看到它已经添加好了。 I then attach the event listener using d3's .on function. 然后,我使用d3的.on函数附加事件监听器。 And I obtain what I believe to be the SVG element on which the event is being fired by d3.select(this) . 并且我获得了我认为是d3.select(this)在其上触发事件的SVG元素。 Indeed, I can modify the SVG attributes of it this way, as you can see when hovering the small rectangle in my codepen given below. 确实,我可以通过这种方式修改它的SVG属性,正如您在下面给出的代码笔中将小矩形悬停时所看到的。

The Problem 问题

Although I can confirm that my object was added to the SVG object, when I retrieve the SVG element inside the event handler, it has everything but that object reference. 尽管我可以确认我的对象已添加到SVG对象,但是当我在事件处理程序中检索SVG元素时,它具有对象引用之外的所有内容。

I reduced this problem into the code in this codepen - where logging demonstrates the problem - hover the rectangle to check it out. 我将此问题简化为该代码的代码-日志记录显示了该问题-将鼠标悬停在矩形上可以将其检出。

What am I doing wrong that results in this non-availability of the added object reference? 我做错了什么导致添加的对象引用不可用? How should I correctly accomplish using an object reference inside the SVG element, or work-around this? 如何正确使用SVG元素内的对象引用或解决此问题?

Code description of the problem: 问题的代码说明:

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.... */
  })

The reason that your sample code doesn't work as you expect is because rectangle is not a reference to the rectangle element, it is a reference to a d3 selection which just happens to only contain a single element. 您的示例代码无法按预期工作的原因是,因为rectangle 不是对矩形元素的引用,而是对d3选择的引用,该选择恰好只包含一个元素。 Creating a different selection of the same element later will not give you access to a property of the initial selection. 稍后为同一元素创建其他选择将使您无法访问初始选择的属性。

(To get your head around it: think of the actual SVGRectElement object as a library book. That book is inside your backpack (the d3 selection referenced by rectangle ). You create some notes about the book ( __test__ ), and also add them to your backpack. Then you do other things, and later someone gets the same library book out and puts it in a different backpack. For many uses, the effect is the same: a backpack containing a specific book. If you wanted to read the book or take it to a specific class, it wouldn't matter which backpack it was inside of. However, that person isn't going to be able to magically find your notes in their backpack!) (要想弄清楚,请考虑一下实际的SVGRectElement对象是一本图书馆书。那本书在背包里(d3选择由rectangle引用)。您为书创建了一些注释( __test__ ),并将它们添加到您的背包,然后做其他事情,后来有人拿出同一本图书馆书并将其放在不同的背包中,对于许多用途来说,效果是一样的:一个装有特定书本的背包。如果您想阅读该书或将其交给一个特定的类,它不会不管哪个背包它的内部。但是,这个人是不是要能够奇迹般地发现在他们的背包你的笔记!)

If you had done 如果你做了

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

and then 接着

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

in the event handler, it would work. 在事件处理程序中,它将起作用。

But you can do this much more easily by using d3 data functions to associate a data object with each element and then access it directly as the first parameter of your event handling function. 但是 ,通过使用d3数据函数将数据对象与每个元素关联,然后直接将其作为事件处理函数的第一个参数进行访问,您可以更加轻松地完成此操作。 Spend some time with the tutorials to figure out how to get the most out of d3. 花一些时间学习这些教程,以了解如何充分利用d3。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM