使用d3.js更新表格数据

时间:2018-07-14 13:12:38

标签: javascript d3.js

我希望有一个包含5行的表,该表会定期更新。目前,它正在运行,如in this fiddle所示。

index.html

<table id="attack-table" class="table table-sm table-dark table-responsive">
<thead>
<tr>
  <th>Source Country</th>
  <th>Target Country</th>
  <th>Date Created</th>
  <th>Attack Type</th>
  <th>Parameter</th>
</tr>

index.js

(function() {
function updateTable(alerts) {
const table = d3.select("#attack-table");
const tableBody = table.append("tbody");

tableBody
  .selectAll("tr")
  .data(alerts)
  .enter()
  .append("tr")
  .selectAll("td")
  .data(function(row, i) {
    return [{
        column: "Source Country",
        value: row.country
      },
      {
        column: "Target Country",
        value: row.targetCountry
      },
      {
        column: "Date Created",
        value: row.dateCreated
      },
      {
        column: "Attack Type",
        value: row.analyzerType
      },
      {
        column: "Parameter",
        value: row.requestString
      }
    ];
  })
  .enter()
  .append("td")
  .attr("class", "small")
  .text(function(d) {
    return d.value;
  });
}
const alerts = [{
  "analyzerType": "VNC(vnclowpot)",
  "clientDomain": true,
  "country": "RU",
  "countryName": "Russian Federation",
  "dateCreated": "2018-07-13 19:29:42",
  "destLat": "25.66669999999999",
  "destLng": "-100.3167",
  "id": "48a140b7df45cdb824eb898b3647f9b9",
  "requestString": "",
  "sourceLat": "55.75219999999999",
  "sourceLng": "37.6156",
  "targetCountry": "MX"
},
{
  "analyzerType": "VNC(vnclowpot)",
  "clientDomain": true,
  "country": "RU",
  "countryName": "Russian Federation",
  "dateCreated": "2018-07-13 19:29:42",
  "destLat": "50.10249999999999",
  "destLng": "8.629899999999992",
  "id": "cdf7b9ebff8e49073bc54998c32542f3",
  "requestString": "",
  "sourceLat": "55.75219999999999",
  "sourceLng": "37.6156",
  "targetCountry": "DE"
},
{
  "analyzerType": "Network(honeytrap)",
  "clientDomain": true,
  "country": "-",
  "countryName": "-",
  "dateCreated": "2018-07-13 19:29:42",
  "destLat": "50.708021",
  "destLng": "7.129191",
  "id": "06f701c097bc0df0c091ad0e74272377",
  "requestString": "Attack on port 5900/tcp",
  "sourceLat": "50.708021",
  "sourceLng": "7.129191",
  "targetCountry": "PIR"
},
{
  "analyzerType": "Network(Dionaea)",
  "clientDomain": true,
  "country": "NL",
  "countryName": "Netherlands",
  "dateCreated": "2018-07-13 19:29:42",
  "destLat": "50.708021",
  "destLng": "7.129191",
  "id": "86d45dd8856c95fe4c9d950ac6075ff3",
  "requestString": "Attack on port 5060/udp",
  "sourceLat": "52.38239999999999",
  "sourceLng": "4.899499999999989",
  "targetCountry": "PIR"
},
{
  "analyzerType": "Network(Dionaea)",
  "clientDomain": true,
  "country": "US",
  "countryName": "United States",
  "dateCreated": "2018-07-13 19:29:42",
  "destLat": "50.708021",
  "destLng": "7.129191",
  "id": "d186782a94d472b8b967edf748fffe47",
  "requestString": "Attack on port 3306/tcp",
  "sourceLat": "40.498099999999994",
  "sourceLng": "-74.3194",
  "targetCountry": "PIR"
},
{
  "analyzerType": "Network(Dionaea)",
  "clientDomain": true,
  "country": "NL",
  "countryName": "Netherlands",
  "dateCreated": "2018-07-13 19:29:42",
  "destLat": "50.708021",
  "destLng": "7.129191",
  "id": "d6447b9b4883a26e08f8c302c3e3efea",
  "requestString": "Attack on port 5060/udp",
  "sourceLat": "52.38239999999999",
  "sourceLng": "4.899499999999989",
  "targetCountry": "PIR"
},
{
  "analyzerType": "VNC(vnclowpot)",
  "clientDomain": true,
  "country": "RU",
  "countryName": "Russian Federation",
  "dateCreated": "2018-07-13 19:29:42",
  "destLat": "50.10249999999999",
  "destLng": "8.629899999999992",
  "id": "f847fd75a20a9a89d92c75ee34a1f704",
  "requestString": "",
  "sourceLat": "55.75219999999999",
  "sourceLng": "37.6156",
  "targetCountry": "DE"
},
{
  "analyzerType": "VNC(vnclowpot)",
  "clientDomain": true,
  "country": "-",
  "countryName": "-",
  "dateCreated": "2018-07-13 19:29:42",
  "destLat": "50.708021",
  "destLng": "7.129191",
  "id": "eaf7035d34072636afe55014140dffcd",
  "requestString": "",
  "sourceLat": "50.708021",
  "sourceLng": "7.129191",
  "targetCountry": "-"
},
{
  "analyzerType": "Webpage",
  "clientDomain": true,
  "country": "US",
  "countryName": "United States",
  "dateCreated": "2018-07-13 19:29:42",
  "destLat": "50.708021",
  "destLng": "7.129191",
  "id": "b55ab3597ea3cdc794b4fcdc11eb590e",
  "requestString": "/gnu/servlet/1220/base.php?eval=",
  "sourceLat": "42.813500000000005",
  "sourceLng": "-70.886",
  "targetCountry": "PIR"
},
{
  "analyzerType": "VNC(vnclowpot)",
  "clientDomain": true,
  "country": "RU",
  "countryName": "Russian Federation",
  "dateCreated": "2018-07-13 19:29:42",
  "destLat": "50.10249999999999",
  "destLng": "8.629899999999992",
  "id": "7be4654b45d39543e6a60f9cecf76b85",
  "requestString": "",
  "sourceLat": "55.75219999999999",
  "sourceLng": "37.6156",
  "targetCountry": "DE"
},
{
  "analyzerType": "VNC(vnclowpot)",
  "clientDomain": true,
  "country": "RU",
  "countryName": "Russian Federation",
  "dateCreated": "2018-07-13 19:29:42",
  "destLat": "25.66669999999999",
  "destLng": "-100.3167",
  "id": "1ac340048643fb3e4f0891828bbe74d2",
  "requestString": "",
  "sourceLat": "55.75219999999999",
  "sourceLng": "37.6156",
  "targetCountry": "MX"
}
]
// this is done periodically in the app with diff data points
/* setInterval(updateTable.bind(null,alerts), 1000) */
updateTable(alerts)
})();

我想实现的是更新5行数据,而不是将它们彼此堆叠。我是d3 js的新手,所以一个可以理解的解决方案将真正帮助我理解d3的更新和退出概念。

2 个答案:

答案 0 :(得分:0)

如果您只是想让表在每次执行#include <math.h> 函数时都反映最新的数据集,那么您可以删除updateTable(),然后在每次更新时重新绘制表。例如,您可以在tbody函数的开头添加以下内容:

updateTable()

顺便说一句,对于用定期刷新的数据构建表,d3可能是过大的了(但也许您计划使用比此处指示的更多的钟声)。

答案 1 :(得分:0)

首先,这是一个可工作的codepen(希望这是您想要的):https://codepen.io/anon/pen/ajdbBZ?editors=0011

因此,您需要做的第一件事是在最初创建行时加载5行数据,我通过使用.slice和“警报”数组的起始位置变量以及多少变量来完成此操作您将以“增量”获取的记录:

 : Searching for device matching iPhone 6...
 : Booting device 7F2124D7-7A75-4702-9A88-926D0C5B884A
 : running "/usr/bin/xcrun simctl io 7F2124D7-7A75-4702-9A88-926D0C5B884A screenshot "/dev/null"" returned 2
7: stderr: An error was encountered processing the command (domain=SimulatorKit.SimDisplayScreenshotWriter.ScreenshotError, code=2):
Error creating the image

要更新由上述函数生成的行中的值,我创建了另一个名为“ next”的函数,该函数加载下一组(+1条记录)。通过选择所有'tr'行,将数据设置为新的数据切片,然后使用.each来完成此操作,我在每个'td'单元格上调用了一个函数来更改数据值和文本。您可以在这里看到它:

var startPos = 0,
    increment = 5;
function generateTable(alerts) {
  const table = d3.select("#attack-table");
  const tableBody = table.append("tbody");

  tableBody
    .selectAll("tr")
    .data(alerts.slice(startPos, (startPos + increment)))
    .enter()
    .append("tr")
    .selectAll("td")
    .data(function(row, i) { ...