d3js:创建一个可折叠的表格&嵌套数据的问题

时间:2016-03-29 00:14:45

标签: javascript jquery d3.js

我正在努力在d3js中创建一个可折叠表,并且遇到了我正在使用的数据结构的嵌套特性问题。数据的组织如下:

var source = [
{name: William, age: 40, children: [{name: Billy, age: 10},{name:Charles, age: 12}]},
{name: Nancy, age: 35, children: [{name: Sally, age:8}]}
]

当我第一次创建表时,我将children数组移动到每个相应父项中的_children对象中,如下所示:

tableData.forEach(function(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
});

使用d3js'典型的数据输入我可以填充表格中每个父级的行和坐标。

source.forEach(function(d) {
    d.x = x0;
    d.y = y0;
    var parentX = x0,
      parentY = y0;
    y0 += barHeight + padding;
    if (d.children) {
      d.children.forEach(function(data) {
        data.x = x0;
        data.y = y0;
        data.parentX = parentX;
        data.parentY = parentY;
        y0 += barHeight + padding;
        shownChildren.push(data);
      })
    }
  });

我使用通常的数据选择方法:

var tableRow = tableSvg.selectAll('.tableRow')
  .data(source);

var rowEnter = tableRow.enter()
  .append("g")
  .classed("tableRow", true)
  .attr("transform", function(d) {
    return "translate(" + d.x + "," + d.y + ")"
  });

除了放置代表每行的矩形:

var rowRect = rowEnter.append("rect")
  .attr("height", barHeight)
  .attr("width", barWidth)
  .style("fill", color)
  .on("click", click);

var rowText = rowEnter.append("text")
  .attr("dy", 15)
  .attr("dx", 5.5)
  .text(function(d) {
    if (d.name.length > 70) {
      return d.name.substring(0, 67) + "...";
    } else {
      return d.name;
    }
  })
  .on("click", click);

点击一行后,行会移动以为添加的子行留出空间,并将_children数组移回children,其中上面的代码为每个孩子分配一个位置然后显示:

function click(d) {
  if (d.children) {
    d._children = d.children;
    d.children = null;
  } else {
    d.children = d._children;
    d._children = null;
  }
  updateTable(source);
}

但是,当我使用与上述父项完全相同的方式为每个子项创建行时,会出现问题。我当前的实现构建了一个数组shownChildren(如第三个代码块中所示),并用子项填充表中的空白。最初,实现似乎工作正常,但是当您单击行时,每个子行都会更改位置。

我没有猜测目前导致问题的是什么。

这是我在jsfiddle上拥有的代码的简要说明。

1 个答案:

答案 0 :(得分:0)

我遇到的问题是我每次都会用不同数量的孩子重建shownChildren数组。我通过将所有children_children添加到shownChildren数组(总是以相同的顺序!)并将每个_children隐藏在各自的父母后面来解决了这个问题

更新了jsfiddle