【问题标题】:How to handle heavily nested objects with D3如何使用 D3 处理重度嵌套对象
【发布时间】:2017-06-07 07:32:39
【问题描述】:

免责声明:我对 D3 很陌生,所以我确信这是可能的,但还没有弄清楚要搜索什么来解决这个问题。

我正在尝试使用 D3 创建一个可视化,该可视化从一个充满嵌套 JSON 对象/数组的大型数组中提取。举例来说,假设我的对象如下所示:

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 来创建我需要的内容。但是,当我附加嵌套的 div 时,我不能再使用父级的数据进行循环,并且似乎无法在 .data() 的自动循环中找到父级 div 的索引。

真的,我想做的是根据 arr[] 的长度创建 div,将一些信息(如“名称”)附加到该 div,然后将一些用于风格目的的 div 附加到根 div,然后得到回到那个根 div 的数据以进行循环。我想使用 D3 来执行此操作,因为我知道这就是它的用途,但此时我已经准备好使用 for 循环来暴力破解它,我知道我所在的索引并且可以在更多情况下使用它嵌套数据。希望这是有道理的,但我完全不知道如何使用 D3 正确地做到这一点。

请询问是否有任何不清楚的地方 - 真的希望弄清楚这一点。谢谢!

【问题讨论】:

    标签: javascript json d3.js nested visualization


    【解决方案1】:

    我不确定我是否完全理解您的问题。使用该数据复制您想要的结构并不困难。您可以根据需要附加任意数量的层并继续访问父数据:

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

    【讨论】:

      猜你喜欢
      • 2011-02-10
      • 1970-01-01
      • 2023-03-18
      • 1970-01-01
      • 1970-01-01
      • 2021-09-03
      • 1970-01-01
      • 1970-01-01
      • 2015-09-13
      相关资源
      最近更新 更多