简体   繁体   中英

Using XML attributes in d3.js

I'm trying to visualise a set of generated XML data using d3.js and while I'm sure this is going to be something obvious, I've hit a problem doing something that I initially thought would be simple - displaying node names using attributes taken from the XML nodes rather than the actual XML node name.

For example, with this XML:

<data>
 <foo id="123" name="fooname1" type="footype1">
   <bar>Hello</bar>
 </foo>
 <foo id="456" name="fooname2" type="footype2">
   <bar>World</bar>
 </foo>
</data>

I'm trying to show the "foo" nodes as circles with the text "fooname1" and "fooname2" (the other attributes would be used later) instead of them both showing "foo". What I've been trying is something like this (minus radius, mouseover and text anchor stuff):

var node = svg.selectAll(".node")
   .data(nodes)
   .enter().append("g")
   .attr("class","node")

   node.append("circle")
   node.append("text")
     .text(function(d) {return d.lastElementChild ? d.attributes.nodeValue:d.localName+": "+d.textContent ; })

;

The idea being that if it's not the last node in the list, the name from the attributes are used and if not, the node content is displayed but d.attributes.nodeValue never returns anything and d.attributes[1].nodeValue which was my second thought returns "d.attributes[1] is undefined".

The console output from console.log(nodes) shows that the attributes are being loaded into the object elements and are sitting in structure like this:

 [object element]
    attributes: [object MozNamedAttrMap]
      0 [object Attr]
        nodeName = id
        nodeValue=123
      1 [object Attr]
        nodeName = name
        nodeValue = fooname1
      2 [object Attr]
        nodeName = type
        nodeValue = footype1
  localName = foo
  textContent= ""

So the data is there, I'm just not picking it up correctly. I think I might be trying to pull it in in the wrong way but some variations using d3.selectAll(d.attributes) didn't seem to return anything either - am I just going about this the wrong way?

Edit: nodes is created as follows:

d3.xml(URL,"application/xml",function(xml) {
var nodes = self.nodes = d3.select(xml).selectAll("*")[0]
});

Where URL is the generated path to a webservice which generates the XML. There's similar handling for links and this is then feeding into a force directed layout - this is pretty much taken from based some examples of force directed XML.

Figured this out and as predicted, it was something obvious!

I was trying to reference the Name attributes using d.attributes.Name which did return an object containing the data but I was then unable to reference it egdattributes.Name.nodeValue would return "d.attributes.Name is not defined". What I hadn't realised was that the attributes have a different nodeType (2 for an attribute node) so can't be accessed in the same way as regular node, instead, using d.getAttribute("Name") returns the data correctly.

I realised the node type difference from this answer JavaScript getAttribute not working and some further research on the node types led me to https://developer.mozilla.org/en-US/docs/Web/API/Element.getAttribute .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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