D3.js在enter()上附加元素但不总是在exit()

时间:2018-06-07 22:23:05

标签: javascript json d3.js

我正在使用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

0 个答案:

没有答案