递归(或迭代)使用d3.js创建嵌套html表? [英] recursively (or iteratively) make a nested html table with d3.js?

查看:279
本文介绍了递归(或迭代)使用d3.js创建嵌套html表?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个嵌套的JSON结构的数组,其中它们有不同的深度,而不是到处都有相同的键集合:

I have an array of nested JSON structures where they have varying depth and not the same set of keys everywhere:

[
    {
        "name":"bob",
        "salary":10000,
        "friends":[
            {
                "name": "sarah",
                "salary":10000
            },
            {
                "name": "bill",
                "salary":5000
            }
        ]
    },
    {
        "name":"marge",
        "salary":10000,
        "friends":[
            {
                "name": "rhonda",
                "salary":10000
            },
            {
                "name": "mike",
                "salary":5000,
                "hobbies":[
                    {
                        "name":"surfing",
                        "frequency":10
                    },
                    {
                        "name":"surfing",
                        "frequency":15
                    }
                ]
            }
        ]
    },
    {
        "name":"joe",
        "salary":10000,
        "friends":[
            {
                "name": "harry",
                "salary":10000
            },
            {
                "name": "sally",
                "salary":5000
            }
        ]
    }
]



我想使用D3来渲染嵌套html表。例如,friends列将具有显示该行中引用的个人的朋友的姓名和工资的表。有时这些表中的一个将有另一个子表的级别。

I wanted to use D3 to render this as nested html tables. For example the friends column will have tables showing the name, and salary of the friends of the individual referenced in the row. Sometimes one of these tables will have another level of a sub table.

我想象的方式是通过递归创建表。我写了一个python程序,它采用这样的JSON结构,并呈现表内的表,最简单的方法是递归。我看到在d3.js文档有一个 .each()你可以调用,我相信是我需要的,我只需要一点点提高到那里( https://github.com/mbostock/d3/wiki/Selections#wiki-each )。

I imagine the way to do this is by recursively creating tables. I wrote a python program that takes a JSON structure like this, and renders tables within tables, and the easiest way to do that was recursively. I see on the d3.js documentation there is a .each() thing you can call, which I am sure is what I need, I just need a little boost getting there (https://github.com/mbostock/d3/wiki/Selections#wiki-each).

那么在D3中有一个很好的方法吗?我发现这个很好的例子来渲染一个二维数据矩阵作为一个表 d3创建链接到csv文件的表。有了这个教程,我能够得到最外层的这个数据结构呈现为一个表,但我仍然坚持如何进入水平递归的需要,因为现在他们只是在表中显示为对象因为我不是对待他们不同于正常的字符串和数字。

So is there a nice way to do this in D3? I found this great example for rendering a 2d matrix of data as a table d3 creating a table linked to a csv file. With that tutorial I was able to get the outer most level of this data-structure rendered as a table, but I am stuck on how to go into levels recursively as needed, as of now they just show up as "Object" in the table since I am not treating them differently from normal strings and numbers.

此外,我发现这个其他问题/答案是类似我的问题,但我真的不太明白JavaScript足以看到在哪里/如何递归发生,重新映射解决方案以适应我的需求:如何处理D3中嵌套多个级别的数据?。在D3中递归或迭代处理嵌套树(如JSON中的JSON数据结构)的任何建议或指针都会非常感谢。

Also I found this other question/answer that is similar to my question, but I really don't understand javascript well enough to see where/how the recursion is happening and readapt the solution to fit my needs: How do I process data that is nested multiple levels in D3?. Any advice or pointers to tutorials on recursively or iteratively processing nested tree like JSON data-structures in D3 would be much appreciated!

推荐答案

递归函数可能是一个好方法。见下面的代码一个可能的实现(假设你的数据存储在 jdata )。有关说明,请参阅代码中的注释,并查看此版本的Gist: http://bl.ocks.org/4085017

A recursive function would probably be good approach. See code below for one possible implementation (assuming your data is stored in jdata). See the comments in the code for some explanation and see this Gist for a live version: http://bl.ocks.org/4085017

d3.select("body").selectAll("table")
    .data([jdata])
  .enter().append("table")
    .call(recurse);

function recurse(sel) {
  // sel is a d3.selection of one or more empty tables
  sel.each(function(d) {
    // d is an array of objects
    var colnames,
        tds,
        table = d3.select(this);

    // obtain column names by gathering unique key names in all 1st level objects
    // following method emulates a set by using the keys of a d3.map()
    colnames = d                                                     // array of objects
        .reduce(function(p,c) { return p.concat(d3.keys(c)); }, [])  // array with all keynames
        .reduce(function(p,c) { return (p.set(c,0), p); }, d3.map()) // map with unique keynames as keys
        .keys();                                                     // array with unique keynames (arb. order)

    // colnames array is in arbitrary order
    // sort colnames here if required

    // create header row using standard 1D data join and enter()
    table.append("thead").append("tr").selectAll("th")
        .data(colnames)
      .enter().append("th")
        .text(function(d) { return d; });

    // create the table cells by using nested 2D data join and enter()
    // see also http://bost.ocks.org/mike/nest/
    tds = table.append("tbody").selectAll("tr")
        .data(d)                            // each row gets one object
      .enter().append("tr").selectAll("td")
        .data(function(d) {                 // each cell gets one value
          return colnames.map(function(k) { // for each colname (i.e. key) find the corresponding value
            return d[k] || "";              // use empty string if key doesn't exist for that object
          });
        })
      .enter().append("td");

    // cell contents depends on the data bound to the cell
    // fill with text if data is not an Array  
    tds.filter(function(d) { return !(d instanceof Array); })
        .text(function(d) { return d; });
    // fill with a new table if data is an Array
    tds.filter(function(d) { return (d instanceof Array); })
        .append("table")
        .call(recurse);
  });    
}

这篇关于递归(或迭代)使用d3.js创建嵌套html表?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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