如何使用 D3 处理大量嵌套的对象
How to handle heavily nested objects with D3
免责声明:我是 D3 的新手,所以我确信这是可能的,但还没有弄清楚要搜索什么才能弄清楚。
我正在尝试使用 D3 创建一个可视化,它从一个充满嵌套 JSON objects/arrays 的大数组中提取。为了举例,假设我的对象看起来像这样:
var arr = [
{
"name":"John",
"info":[
{
"age":31,
"height":6,
"weight":155,
"eyes":"green"
},
{
"age":35,
"height":6,
"weight":165,
"eyes":"green"
}
]
},
{
"name":"Eric",
"info":[
{
"age":29,
"height":5,
"weight":135,
"eyes":"brown"
},
{
"age":30,
"height":5,
"weight":155,
"eyes":"brown"
}
]
}
]
现在,假设我想获取此数据并将其可视化,但需要使用比对象的嵌套级别更多的 div 来设置样式。所以,我想要这样的代码:
<div>
<h1>John</h1>
<div>
<div>
<div>
<h2>Age:31</h2>
<div>
<p>Weight:155</p>
</div>
</div>
<div>
<h2>Age:35</h2>
<div>
<p>Weight:165</p>
</div>
</div>
</div>
</div>
</div>
<div>
<h1>Eric</h1>
<div>
<div>
<div>
<h2>Age:29</h2>
<div>
<p>Weight:135</p>
</div>
</div>
<div>
<h2>Age:30</h2>
<div>
<p>Weight:155</p>
</div>
</div>
</div>
</div>
</div>
现在,如果我没有多余的 div,使用起来会相当简单
var visualization = d3.select("body").selectAll("div")
.data(arr)
.enter()
.append("div");
var person = visualization.selectAll("h1")
.data(function(d){return(d.name)}
.enter()
.append("h1")
.text(function(d){return d});
然后我可以对 div 做同样的事情并循环遍历 d.info 来创建我需要的东西。但是,当我附加嵌套的 divs 时,我不能再使用父级的数据进行循环,并且似乎无法在自动循环中找到父级 div 的索引。 data() 确实如此。
真的,我想做的是根据 arr[] 的长度创建 divs,在 div 上附加一些信息,例如 "name",然后出于文体目的将一些 div 附加到根 div,然后返回到该根 div 的数据以进行循环。我想使用 D3 来执行此操作,因为我知道这是它的构建目的,但在这一点上,我准备使用 for 循环暴力破解它,我知道我所在的索引并且可以在更多的地方使用它嵌套数据。希望这是有道理的,但我完全不知道如何使用 D3 正确地做到这一点。
请询问是否有任何不清楚的地方 - 真的希望弄清楚。谢谢!
我不确定我是否完全理解您的问题。使用该数据复制所需的结构并不困难。您可以根据需要附加任意多个图层并继续访问父数据:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
var arr = [{
"name": "John",
"info": [{
"age": 31,
"height": 6,
"weight": 155,
"eyes": "green"
}, {
"age": 35,
"height": 6,
"weight": 165,
"eyes": "green"
}]
}, {
"name": "Eric",
"info": [{
"age": 29,
"height": 5,
"weight": 135,
"eyes": "brown"
}, {
"age": 30,
"height": 5,
"weight": 155,
"eyes": "brown"
}]
}];
var vis = d3.select("body").selectAll("div")
.data(arr)
.enter()
.append("div");
vis.append("h1")
.html((d) => d.name);
var nestedDivs = vis.append("div").append("div");
var innerDiv = nestedDivs.selectAll("div")
.data((d) => d.info)
.enter()
.append("div");
innerDiv.append("h2")
.html((d) => "Age:" + d.age);
innerDiv.append("div")
.append("span")
.html((d) => "Weight: " + d.weight);
</script>
</body>
</html>
免责声明:我是 D3 的新手,所以我确信这是可能的,但还没有弄清楚要搜索什么才能弄清楚。
我正在尝试使用 D3 创建一个可视化,它从一个充满嵌套 JSON objects/arrays 的大数组中提取。为了举例,假设我的对象看起来像这样:
var arr = [
{
"name":"John",
"info":[
{
"age":31,
"height":6,
"weight":155,
"eyes":"green"
},
{
"age":35,
"height":6,
"weight":165,
"eyes":"green"
}
]
},
{
"name":"Eric",
"info":[
{
"age":29,
"height":5,
"weight":135,
"eyes":"brown"
},
{
"age":30,
"height":5,
"weight":155,
"eyes":"brown"
}
]
}
]
现在,假设我想获取此数据并将其可视化,但需要使用比对象的嵌套级别更多的 div 来设置样式。所以,我想要这样的代码:
<div>
<h1>John</h1>
<div>
<div>
<div>
<h2>Age:31</h2>
<div>
<p>Weight:155</p>
</div>
</div>
<div>
<h2>Age:35</h2>
<div>
<p>Weight:165</p>
</div>
</div>
</div>
</div>
</div>
<div>
<h1>Eric</h1>
<div>
<div>
<div>
<h2>Age:29</h2>
<div>
<p>Weight:135</p>
</div>
</div>
<div>
<h2>Age:30</h2>
<div>
<p>Weight:155</p>
</div>
</div>
</div>
</div>
</div>
现在,如果我没有多余的 div,使用起来会相当简单
var visualization = d3.select("body").selectAll("div")
.data(arr)
.enter()
.append("div");
var person = visualization.selectAll("h1")
.data(function(d){return(d.name)}
.enter()
.append("h1")
.text(function(d){return d});
然后我可以对 div 做同样的事情并循环遍历 d.info 来创建我需要的东西。但是,当我附加嵌套的 divs 时,我不能再使用父级的数据进行循环,并且似乎无法在自动循环中找到父级 div 的索引。 data() 确实如此。
真的,我想做的是根据 arr[] 的长度创建 divs,在 div 上附加一些信息,例如 "name",然后出于文体目的将一些 div 附加到根 div,然后返回到该根 div 的数据以进行循环。我想使用 D3 来执行此操作,因为我知道这是它的构建目的,但在这一点上,我准备使用 for 循环暴力破解它,我知道我所在的索引并且可以在更多的地方使用它嵌套数据。希望这是有道理的,但我完全不知道如何使用 D3 正确地做到这一点。
请询问是否有任何不清楚的地方 - 真的希望弄清楚。谢谢!
我不确定我是否完全理解您的问题。使用该数据复制所需的结构并不困难。您可以根据需要附加任意多个图层并继续访问父数据:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
var arr = [{
"name": "John",
"info": [{
"age": 31,
"height": 6,
"weight": 155,
"eyes": "green"
}, {
"age": 35,
"height": 6,
"weight": 165,
"eyes": "green"
}]
}, {
"name": "Eric",
"info": [{
"age": 29,
"height": 5,
"weight": 135,
"eyes": "brown"
}, {
"age": 30,
"height": 5,
"weight": 155,
"eyes": "brown"
}]
}];
var vis = d3.select("body").selectAll("div")
.data(arr)
.enter()
.append("div");
vis.append("h1")
.html((d) => d.name);
var nestedDivs = vis.append("div").append("div");
var innerDiv = nestedDivs.selectAll("div")
.data((d) => d.info)
.enter()
.append("div");
innerDiv.append("h2")
.html((d) => "Age:" + d.age);
innerDiv.append("div")
.append("span")
.html((d) => "Weight: " + d.weight);
</script>
</body>
</html>