我正在努力在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上拥有的代码的简要说明。
答案 0 :(得分:0)
我遇到的问题是我每次都会用不同数量的孩子重建shownChildren
数组。我通过将所有children
和_children
添加到shownChildren
数组(总是以相同的顺序!)并将每个_children
隐藏在各自的父母后面来解决了这个问题
更新了jsfiddle