使用 D3 获取嵌套 XML 数据

Jas*_*hen 2 javascript d3.js

我的 excel 文件名为thefilehere.xml包含以下信息:

<Main>
  <Name>Rotunda</Name>
  <Age>43</Age>
</Main>
<Main>
  <Name>John</Name>
  <Age>22</Age>
</Main>
Run Code Online (Sandbox Code Playgroud)

作为对 D3 和 XML 文件缺乏经验的人,我试图了解如何从 XML 文件调用嵌套数据。我的基本 HTML 如下:

超文本标记语言

<div id="chart"></div> 
Run Code Online (Sandbox Code Playgroud)

我的 Javascript 不起作用,希望能清楚地说明我想要完成的任务。我想选择主容器(在本例中为Main),然后从那里选择其子容器(在本例中Name为 和Age)。Age是通过图表来显示的。Name是图表上的标签。

JavaScript

  d3.xml("thefilehere.xml", function(err, xml) {
    d3.select("#chart")
    .selectAll("div")
    .data(xml.documentElement.getElementsByTagName("Main"))
    .enter().append("div")
    .style("width", function(d) { return d("Age").textContent * 1 + "px"; })
    .text(d("Name").textContent);
  });
Run Code Online (Sandbox Code Playgroud)

alt*_*lus 5

这个答案补充并建立在@GerardoFurtado 在他的答案中已经完成的工作上,该答案非常好并且非常适合许多情况。然而,由于通常希望留在 D3 中而不破坏其基本操作概念,因此这里是我的仅限 D3(至少是大部分)的解决方案。

由于 D3 不仅限于处理 SVG DOM 树,还能够处理 XML DOM 等,因此您可以轻松地在加载的 XML 文件上使用它的选择。相关代码可能如下所示:

d3.xml(url, (error, xml) => {
  let xmlDoc = d3.select(xml.documentElement);   // wrap the XML document in a D3 selection

  d3.select("body")
    .selectAll("div")
    .data(xmlDoc.selectAll("Main").nodes())      // bind the XML's nodes as data
    .enter().append("div")
      .attr("class", "myDiv")
      .style("width", d => d3.select(d).select("Age").text() * 5 + "px")
      .text(d => d3.select(d).select("Name").text());
});
Run Code Online (Sandbox Code Playgroud)

在进行d3.select(d)inside操作时.style().text()需要注意的是,这实际上将从 XML 的 DOM 中进行选择,而不是从 HTML 的 DOM 中进行选择。由于我们将所选元素绑定为xmlDoc.selectAll("Main")数据,因此d在本例中将引用<Main>XML 的元素。有了这个选择,您就可以通过进行子选择以及通过调用访问其内容.text()等方式来利用 D3 的功能(如果需要)。

看看下面的代码片段,了解一个有效的演示:

d3.xml(url, (error, xml) => {
  let xmlDoc = d3.select(xml.documentElement);   // wrap the XML document in a D3 selection

  d3.select("body")
    .selectAll("div")
    .data(xmlDoc.selectAll("Main").nodes())      // bind the XML's nodes as data
    .enter().append("div")
      .attr("class", "myDiv")
      .style("width", d => d3.select(d).select("Age").text() * 5 + "px")
      .text(d => d3.select(d).select("Name").text());
});
Run Code Online (Sandbox Code Playgroud)
// Set up data to simulate loading from file.
// This can be ignored for the reasoning of this answer; main logic below.
const url = URL.createObjectURL(new Blob([
  `<data>
     <Main>
       <Name>Rotunda</Name>
       <Age>43</Age>
     </Main>
     <Main>
       <Name>John</Name>
       <Age>22</Age>
     </Main>
   </data>`
]));
// End of setup.

// Main logic
d3.xml(url, (error, xml) => {
  let xmlDoc = d3.select(xml.documentElement);

  d3.select("body")
    .selectAll("div")
    .data(xmlDoc.selectAll("Main").nodes())
    .enter().append("div")
      .attr("class", "myDiv")
      .style("width", d => d3.select(d).select("Age").text() * 5 + "px")
      .text(d => d3.select(d).select("Name").text());
});
Run Code Online (Sandbox Code Playgroud)
.myDiv{
  background-color: lightblue;
  margin: 4px;
}
Run Code Online (Sandbox Code Playgroud)

  • 好答案。有趣的是,他们说“URL.createObjectURL()”是一种“实验技术”,但所有主要浏览器都支持它...... (2认同)