我有以下代码,它足以简单地更新嵌套数据模型,但text(null)
部分似乎有点奇怪。
我不确定我是否做得对,或者有更好的方法:
var data = [
{key: 1, values:[1, 2, 3]},
{key: 2, values:[3, 4, 5]},
]
function update(data) {
var table = d3.select('#gogo')
var tr = table.selectAll('tr')
.data(data)
.text(null)
var rowEnter = tr.enter().append('tr')
var td = tr.merge(rowEnter).selectAll("td")
.data(d=>d.values)
.text(d=>d)
cellEnter = td.enter().append("td")
cellEnter.append("span")
.text(d=>d)
}
update(data)
ref()
function ref() {
setInterval(()=>{
data.map(item=> {
for (var i=0; i<3; i++) {
item.values[i] = Math.floor(Math.random() * 100) + 1
}
})
console.log(data)
update(data)
}, 1000)
}
基本上它只是呈现以下html代码:
<table id="gogo"><tr><td><span>1</span></td><td><span>2</span></td><td><span>3</span></td></tr><tr><td><span>3</span></td><td><span>4</span></td><td><span>5</span></td></tr></table>
请有人给我建议。
答案 0 :(得分:1)
我发现以下方式似乎更优雅:
var data = [
{key: 1, values:[1, 2, 3]},
{key: 2, values:[3, 4, 5]},
]
function update(data) {
var table = d3.select('#gogo')
var tr = table.selectAll('tr')
.data(data)
var rowEnter = tr.enter().append('tr')
var td = tr.merge(rowEnter).selectAll("td span")
.data(d=>d.values)
.text(d=>d)
cellEnter = td.enter().append("td")
cellEnter.append("span")
.text(d=>d)
}
update(data)
ref()
function ref() {
setInterval(()=>{
data.map(item=> {
for (var i=0; i<3; i++) {
item.values[i] = Math.floor(Math.random() * 100) + 1
}
})
console.log(data)
update(data)
}, 1000)
}
答案 1 :(得分:1)
你是对的,还有更好的方法。现在你的代码很混乱,它有一些没有意义的东西(比如text(null)
),最重要的是,它不能为任何不同数量的行和单元更新表...这是最多的更新选择的重要特征。
这是我对更新功能的建议:
function update(data) {
var table = d3.select('#gogo');
var tr = table.selectAll('tr')
.data(data);
var rowExit = tr.exit().remove();
var rowEnter = tr.enter().append('tr');
tr = rowEnter.merge(tr);
var td = tr.selectAll("td")
.data(d => d.values);
var cellExit = td.exit().remove();
var cellEnter = td.enter().append("td").append("span");
td = cellEnter.merge(td)
.text(d => d)
}
让我们逐行看。
首先,表格选择:
var table = d3.select('#gogo');
根据该选择,我们将为行创建更新选择:
var tr = table.selectAll('tr')
.data(data);
然后,根据更新选择,我们为行创建输入选择:
var rowEnter = tr.enter().append('tr');
之后,我们合并行的输入和更新选择:
tr = rowEnter.merge(tr);
这允许我们拥有任意数量的行。当然,要拥有真正的更新功能,我们还必须设置退出选择:
var rowExit = tr.exit().remove();
然后,对于下一个级别,即单元格,我们使用merge
执行几乎相同的操作,更新,退出和输入选择:
var td = tr.selectAll("td")
.data(d => d.values);
var cellExit = td.exit().remove();
var cellEnter = td.enter().append("td").append("span");
td = cellEnter.merge(td)
.text(d => d);
以下是使用ref
功能的演示:
var data = [{
key: 1,
values: [1, 2, 3]
},
{
key: 2,
values: [3, 4, 5]
},
]
function update(data) {
var table = d3.select('#gogo');
var tr = table.selectAll('tr')
.data(data);
var rowExit = tr.exit().remove();
var rowEnter = tr.enter().append('tr');
tr = rowEnter.merge(tr);
var td = tr.selectAll("td")
.data(d => d.values);
var cellExit = td.exit().remove();
var cellEnter = td.enter().append("td").append("span");
td = cellEnter.merge(td)
.text(d => d)
}
update(data)
ref()
function ref() {
setInterval(() => {
data.map(item => {
for (var i = 0; i < 3; i++) {
item.values[i] = Math.floor(Math.random() * 100) + 1
}
})
update(data)
}, 1000)
}
table, tr, td {
border: 1px solid gray;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<table id="gogo"></table>
最后,为了向您展示现在更新函数确实更新了表中任何数量的元素,我重构了您的ref
函数来创建具有随机行数(1到5)的数据,以及随机数的细胞,也是1到5:
var data = [{
key: 1,
values: [1, 2, 3]
},
{
key: 2,
values: [3, 4, 5]
},
]
function update(data) {
var table = d3.select('#gogo');
var tr = table.selectAll('tr')
.data(data);
var rowExit = tr.exit().remove();
var rowEnter = tr.enter().append('tr');
tr = rowEnter.merge(tr);
var td = tr.selectAll("td")
.data(d => d.values);
var cellExit = td.exit().remove();
var cellEnter = td.enter().append("td").append("span");
td = cellEnter.merge(td)
.text(d => d)
}
update(data)
ref()
function ref() {
setInterval(() => {
data = d3.range(~~(Math.random() * 5) + 1).map(function(d) {
return {
key: d,
values: d3.range(~~(Math.random() * 5) + 1).map(function(d) {
return ~~(Math.random() * 20)
})
}
})
update(data)
}, 1000)
}
table,
td,
tr {
border: 1px solid gray;
}
<script src="https://d3js.org/d3.v5.min.js"></script>
<table id="gogo"></table>