d3 数据更新 CSV - 不知道如何更新 table 个单元格

d3 data update CSV - can't figure out how to update table cells

我有一个输出以下数据的 haproxy 状态端点:

我想解析它的输出并构建一个漂亮的交互式仪表板(在这种情况下监视哪些 Riak 节点在给定时间启动或关闭。

我写了以下内容:

<!DOCTYPE html>
 <html lang="en">
 <head>
     <meta charset="UTF-8">
     <title>dadsa</title>
 </head>
 <body>
 <div id="viz"></div>
 <script src="//d3js.org/d3.v3.min.js" charset="utf-8"></script>
 <script>
 var hosts = [];
 var url = "http://localhost:8666/haproxy-csv";
 function update() {
     d3.csv(url, function(data) {
     hosts = data.filter(
             function(d){
                 console.log(JSON.stringify(  d) );
                 console.log(Object.keys(d));
                 console.log(d["# pxname"]);
                 return d["# pxname"] == "riak_backend_http"
                         && d["svname"] != "BACKEND";
             }
     ).map(function(d){
         return {"label": d["svname"],"value": d["status"]};
     });
     d3.select("#viz")
             .append("table")
             .style("border-collapse", "collapse")
             .style("border", "2px black solid")
             .selectAll("tr")
             .data(hosts)
             .enter().append("tr")
             .selectAll("td")
             .data(function(d){
                 return [
                     d["label"], d["value"]
                 ];
             })
             .enter().append("td")
             .style("border", "1px black solid")
             .style("padding", "5px")
             .on("mouseover", function(){d3.select(this).style("background-color", "aliceblue")})
             .on("mouseout", function(){d3.select(this).style("background-color", "white")})
             .text(function(d){return d;})
             .style("font-size", "12px");
 });
 }
 update();
 setInterval(update, 1000);
 </script>
 <button onclick="alert(JSON.stringify(hosts[0]))"> see value </button>
 <div id="svg"/>
 </body>
 </html>

该代码运行良好,有一个小缺陷。它会在每次更新时不断附加一个新的 table 元素。我已经多次重写这段代码,但无论我写什么,似乎只更新一次。

这是当前输出的样子:

我对 d3 真的一无所知,所以我什至不确定我到底应该绑定或挂钩什么。

有什么指点吗?

为什么不在每次更新时删除 table 元素。 添加这一行

d3.csv(url, function(data) {
   d3.select("#viz").select("table").remove();//removes the table
   //other code as usual

每次更新都会得到一个新的 table,因为每次在更新函数中执行此操作时,您实际上都会附加一个新的 table。

...
d3.select("#viz")
   .append("table")
...

而是通过 HTML 标签或使用 javascript 预先创建您的 table。在更新函数之外创建它。比如说:

var myTable = d3.select("#viz")
               .append("table")
               .style("border-collapse", "collapse")
               .style("border", "2px black solid");

现在您已经设置了 table,我们可以使用 enter()、exit() 和 update() 的 'D3.js way' 更新它,如下所示:

//bind the data to rows
var rows = myTable.selectAll("tr").data(hosts); 
//append as needed using enter()
rows.enter().append("tr");
//remove placeholders in exit
rows.exit().remove(); 

//bind the data to columns in each row
var columns = myTable.selectAll("tr")
                     .selectAll("td")
                     .data(function(d){
                       return [
                         d["label"], d["value"]
                       ];
                     });

//enter and exit as above
columns.enter().append("td");
columns.exit().remove();

//finally update the columns
myTable.selectAll("td")
         .style("border", "1px black solid")
         .style("padding", "5px")
         .on("mouseover", function(){d3.select(this).style("background-color", "aliceblue")})
         .on("mouseout", function(){d3.select(this).style("background-color", "white")})
         .text(function(d){return d;})
         .style("font-size", "12px");

希望对您有所帮助。