首页 > 解决方案 > 使用键值对数组作为数据更新表

问题描述

我正在尝试创建一个带有作为数据传递的键值数组的表。我希望它能够随着新数据的传递而更新。我无法附加它(当前代码)和/或更新它(以前的代码)。有什么建议么?

这是我当前的代码:

 let tr = table.selectAll('tr')
                        .data(arr);
        
tr.exit().remove();
                        
tr.enter()
            .append('tr')
            .merge(tr)
            .each(function(d) {
                let td = d3.select(this)
                    .selectAll('td')
                    .data(arr);

                td.exit()
                    .remove();

                td = td.enter()
                    .append('td')
                    .merge(td)
                    .html(d => d.key);
                td = td.enter()
                    .append('td')
                    .merge(td)
                    .html(d => d.value);

            });
            
tr.exit().remove();

以前的迭代 - 不能正确更新,但会正确附加每个键和对应的值:

let tr = table.selectAll('tr')
                        .data(arr);
tr.exit().remove();
                        
tr.enter()
            .append('tr')
            .each(function(d) {
                let td = d3.select(this);
                for (let col in d) {
                    td
                        .append('td')
                        .html(d[col]);
                }
});

tr.exit().remove();

标签: javascripthtmld3.js

解决方案


几点:

  1. 命名您的选择,例如:const trExit = tr.exit().remove();
  2. D3 选择是不可变的。因此,在合并时重新分配(如果您稍后引用该选择),例如:tr = trEnter.merge(tr);
  3. 为 和创建嵌套的进入-更新-退出选择<tr><td>然后删除each

鉴于您的(我假设)数据结构,它可能是:

let tr = table.selectAll('tr')
    .data(data, d => d.key);

const trExit = tr.exit().remove();

const trEnter = tr.enter().append("tr");

tr = trEnter.merge(tr);

let td = tr.selectAll("td")
    .data(d => Object.values(d));

const tdExit = td.exit().remove();

const tdEnter = td.enter().append("td");

td = tdEnter.merge(td);

td.html(d => d);

您不需要 的出口<td>,因为在我看来,表格总是有 2 列。

这是一个基本的演示:

const dataArray = [{
  key: "foo",
  value: 11
}, {
  key: "bar",
  value: 12
}, {
  key: "baz",
  value: 13
}, {
  key: "foobar",
  value: 14
}, {
  key: "foobaz",
  value: 15
}, {
  key: "barbaz",
  value: 16
}];

const table = d3.select("body").append("table");

d3.interval(() => update(dataArray.slice(-(~~(Math.random() * dataArray.length)))), 1000);

function update(data) {
  let tr = table.selectAll('tr')
    .data(data, d => d.key);

  const trExit = tr.exit().remove();

  const trEnter = tr.enter().append("tr");

  tr = trEnter.merge(tr);

  let td = tr.selectAll("td")
    .data(d => Object.values(d));

  const tdExit = td.exit().remove();

  const tdEnter = td.enter().append("td");

  td = tdEnter.merge(td);

  td.html(d => d);
};
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>


推荐阅读