将JavaScript对象与SVG元素相关联 [英] associating a javascript object to an SVG element

查看:147
本文介绍了将JavaScript对象与SVG元素相关联的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

目标



我想将一个 d3.js 建立的SVG元素与JavaScript物件建立关联当SVG元素在事件侦听器上可用时,我可以直接从它跟踪回javascript对象。



(动机)



我有许多SVG元素每个在逻辑上与包含与其相关的结构化数据的一个对象相关联。该数据决定了在任何SVG元素触发事件时该做什么,并且对于每个元素都不同



我的尝试



我只是将对象添加为SVG元素的新属性。我可以看到它被添加好了。
然后我使用d3的 .on 函数附加事件监听器。
我获得了我相信是由 d3.select(this)触发事件的SVG元素。事实上,我可以这样修改它的SVG属性,你可以看到当我在我的codepen中的小矩形悬停下面给出。



问题



虽然我可以确认我的对象被添加到SVG对象,当我在事件处理程序中检索SVG元素时,它具有所有 对象引用。



我将此问题转换为此 codepen - 其中日志记录显示了问题 - 将矩形悬停在其上检查。



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



代码描述问题:



  rectangle = main.append('rect')
.style('fill','#0000FF')

.attr('height',30)
.attr('stroke-width','0px')
.style('fill-opacity','1' width',30)
.attr('id','1')

rectangle .__ test__ ='test'


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


解决方案

示例代码不工作的原因expect是因为 rectangle 不是对矩形元素的引用,它是对d3选择的引用,只是刚好只包含一个元素。



(让你的头脑周围:想想实际的 SVGRectElement 对象作为图书馆书。这本书在你的背包里(d3选择引用 rectangle 关于这本书的注释( __ test __ ),并将它们添加到你的背包里,然后你做其他事情,后来有人得到相同的图书馆书,背包,对于许多用途,效果是一样的:一个背包包含一本特定的书。如果你想读这本书或把它带到一个特定的类,这不重要但

如果您已完成

  rectangle.node().__ test__ =test 
//使用.node()从d3选择
//中提取第一个元素,然后为它分配一个新的属性值

,然后

  console.dir(this .__ test__); 
//`this`直接引用矩形元素
//其上面添加了测试属性

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



,您可以通过使用d3数据函数将数据对象与每个元素关联,然后直接访问它,事件处理函数的第一个参数。 花一些时间与教程,了解如何充分利用d3。


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. 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. That data determines what to do when the event fires for any of those SVG elements, and is different for each of them

My Attempt

I simply add the object as a new property for the SVG element. I can see it's been added okay. I then attach the event listener using d3's .on function. And I obtain what I believe to be the SVG element on which the event is being fired by d3.select(this). 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.

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.

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?

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. 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!)

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. Spend some time with the tutorials to figure out how to get the most out of d3.

这篇关于将JavaScript对象与SVG元素相关联的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆