我正在使用d3为学生实验室中无响应计算机的数据集创建一堆列表项。数据看起来像这样
{
"LabName": "All",
"Computers": [
{
"Hostname": "computer76",
"Lab": "Lab-101"
},
{
"Hostname": "computer78",
"Lab": "Lab-101"
},
{
"Hostname": "computer117",
"Lab": "Lab-211"
}
]
}
使用这些数据我想填充一个由实验室组织的标题
的列表我通过使用另一个列出所有实验室的数据集来制作容器,以便容器准备就绪。
容器看起来像这样
<div class="notify" id="Lab-101">
<h4>Lab-101</h4>
</div>
在我的第一次尝试中,我尝试浏览数据(计算机),并且每台计算机都将数据过滤到该实验室中的计算机,然后将该数据绑定到要显示的特定div中的li
s那些物品。然后,自从该实验室完成后,如果它是同一个实验室,我将跳过下一台计算机。
我收到了输入项,但并不总是退出。
studentsDown = thisLabsDownData["Computers"];
// studentsDown is sorted on "Lab"
var prevLab = null;
studentsDown.forEach(function (val, ind, obj) {
var labName = val.Lab;
if (prevLab != labName) {
var thisLabsComputers = studentsDown.filter(function (d) { return d.Lab == labName });
thisLabsComputers.sort(GetSortOrder("Hostname"));
var selector = "#notify-student-" + labName;
var stuItems = d3.select(selector).selectAll("li")
.data(thisLabsComputers, function (d) { return d.Hostname; });
stuItems.enter().append("li")
.html(function (d) { return d.Hostname; });
stuItems.exit().remove();
}
prevLab = labName;
});
尝试2
我已经处理了以前的一组数据,这些数据的格式略有不同,但不需要附加到单个容器,因此我首先将数据转换为以下格式
[
{
"LabName": "Lab-211",
"Computers": [
"computer117"
]
},
{
"LabName": "Lab-101",
"Computers": [
"computer76",
"computer78"
]
}
]
然后
studentLabs.forEach(function (val, ind, obj) {
val.Computers.sort();
labName = val.LabName;
var selector = "#notify-student-" + labName;
var stuItems = d3.select(selector).selectAll("li")
.data(val.Computers, function (d, i) { return d; });
stuItems.enter().append("li")
.html(function (d, i) { return d; });
stuItems.exit().remove();
});
我想也许这个标题弄乱了项目的索引,所以我把它移到了一个父元素
<div id="lab-student-RH-106">
<h4>RH-106</h4>
<div class="notify" id="notify-student-RH-106">
</div>
</div>
但新项目仍然出现但不退出
关于行为的一些其他说明
如果实验室中已有列表项,则输入和退出将起作用。如果实验室中没有物品并且同时输入3个物品,则退出对任何物品都不起作用,它们会停留。我在忽视或不理解的是什么?
与此同时,我将尝试摆脱容器并将其恢复到基础,看看我是否可以让它工作并再次构建它。
我也有jQuery 3.1.1并且想知道这是否存在干扰,尝试从没有jQuery的API获取数据的尝试都没有成功,因此我无法将其删除并进行测试。我认为这不太可能,但值得一提。
进度
我现在几乎完全工作了。到目前为止,关键方面是使用数据添加实验室容器,然后使用.each()
对数据进行维护,并使用this
以便维护元素并钻取以添加计算机{ {1}}秒。
li
问题是我想在每次计算机启动或离开数据时创建通知。这允许我这样做,除非实验室退出数据(因为所有计算机现在都可用),因为这意味着没有实验室项目可以钻进来为计算机项目抛出var labItems = d3.select("#studentsDownDetail").selectAll("div")
.data(studentLabs, function (d, i) { return d.LabName; });
labItems.enter().append("div")
.html(function (d, i) { return "<h4>" + d.LabName + "</h4>" })
.attr("id", function (d, i) { return "notify-student-" + d.LabName });
labItems.each(function (d, i) {
var thisOne = d3.select(this).selectAll("li")
.data(d.Computers, function (d, i) { return d });
thisOne.enter().append("li")
.html(function (d, i) { return d });
thisOne.exit().each(function (d, i) { /* some extra stuff here */ }).remove();
});
labItems.exit().each(function (d, i) { /* something here */ }).remove();
。
可能可行 - 非常接近!
因为实验室仅在第一次更新时添加,并且其中的计算机仅在下次更新时添加。在.exit
上添加.each
函数以及'更新'应该可以解决这个问题。
最终拼图
.enter