在追加元素之前过滤它们?

时间:2016-11-18 11:10:36

标签: d3.js

以下代码块来自D3 documentation

var matrix = [
  ["A", "B"],
  ["A", "B"]
];

var tr = d3.select("body").append("table").selectAll("tr")
  .data(matrix)
  .enter().append("tr");

var td = tr.selectAll("td")
  .data(function(d) { return d; })
  .enter().append("td")
  .text(function(d) { return d; });

...输出此标记:

<table>
  <tr>
    <td>A</td>
    <td>B</td>
  </tr>
  <tr>
    <td>A</td>
    <td>B</td>
  </tr>
</table>

是否可以调整(使用.filter?)输出:

<table>
  <tr>
    <td rowspan="2">A</td>
    <td>B</td>
  </tr>
  <tr>
    <td>B</td>
  </tr>
</table>

CodePen

1 个答案:

答案 0 :(得分:1)

你确实可以使用过滤器,但我的解决方案是在之后附加

可以一步完成,但两个步骤更具说服力:

var filtered = d3.selectAll("td").filter(function(d){
    return d=="A"
});

这将返回所有<td>与A的选择。然后,我们根据rowspan的总数设置第一个<td>,并删除所有其余内容:

filtered.each(function(d, i) {
    if (i == 0) {
        d3.select(this).attr("rowspan", filtered.nodes().length)
    } else {
        d3.select(this).remove()
    }
});

使用此规则,我们可以拥有更长的数组,例如:

var matrix = [
    ["A", "B"],
    ["A", "B"],
    ["A", "B"],
    ["A", "B"]
];

这是一个演示:

var matrix = [
    ["A", "B"],
    ["A", "B"],
    ["A", "B"],
    ["A", "B"]
];

var tr = d3.select("body").append("table").selectAll("tr")
    .data(matrix)
    .enter().append("tr");

var td = tr.selectAll("td")
    .data(function(d) {
        return d;
    })
    .enter().append("td")
    .text(function(d) {
        return d;
    });

var filtered = d3.selectAll("td").filter(function(d) {
    return d == "A"
});
filtered.each(function(d, i) {
    if (i == 0) {
        d3.select(this).attr("rowspan", filtered.nodes().length)
    } else {
        d3.select(this).remove()
    }
})
tr, td {
    padding: 10px;
    text-align: left;
    border: 1px solid gray;
}
<script src="https://d3js.org/d3.v4.min.js"></script>