递归地(或迭代地)用d3.js创建一个嵌套的html表?

Joh*_*ohn 12 html javascript d3.js

我有一组嵌套的JSON结构,它们的深度各不相同,而且各处都没有相同的密钥集:

[
    {
        "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
            }
        ]
    }
]
Run Code Online (Sandbox Code Playgroud)

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

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

那么在D3中有一个很好的方法吗?我找到了一个很好的例子,用于将2d数据矩阵呈现为表创建链接到csv文件的表.通过该教程,我能够将这个数据结构的最外层级别呈现为一个表格,但我仍然坚持如何根据需要递归进入各级别,因为现在它们只是在表格中显示为"对象"因为我不会将它们与正常的字符串和数字区别对待.

另外我发现这个问题/答案与我的问题类似,但我真的不太了解javascript,看看递归发生的位置和方式,并重新解决方案以满足我的需求:我如何处理数据是在D3中嵌套多个级别?.任何关于递归或迭代处理嵌套树(如D3中的JSON数据结构)的教程的建议或指针都将非常感激!

nau*_*tat 18

递归函数可能是很好的方法.有关一种可能的实现,请参阅下面的代码(假设您的数据存储在其中jdata).请参阅代码中的注释以获得一些解释,并查看实时版本的Gist: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);
  });    
}
Run Code Online (Sandbox Code Playgroud)

  • @msqar - 不,你只需要指定它是UTF-8:请参阅https://github.com/mbostock/d3/wiki/Upgrading-to-3.0.你需要一个doctype,一个<meta charset ="UTF-8">标签,你的脚本需要像这样包含:<script src ="http://d3js.org/d3.v3.min.js"charset = "UTF-8"?> </ SCRIPT> (3认同)