繁体   English   中英

D3更新数据,html表中的行数,最后一列中的svgs动画

[英]D3 update data, number rows in html table, animate svgs in last column

我正在尝试使用D3更新HTML表中的数据。 我需要更改多列中的数据,更新行数,并根据每个新数据数组为每行中的SVG设置动画。 我已经尝试了多次尝试,教程,文档,并且我相信对于熟悉该库的人来说,这是一个简单的尝试。

我在代码tbody.selectAll('tr').remove();注释过的一种方法tbody.selectAll('tr').remove(); 只是擦拭桌子上的所有行。 但是,由于没有起始位置,因此无法为SVG设置动画。

尽管我是D3的新手,但我目前使用的方法也不对,所以我不确定为什么。 当输入新数据时,它不能正确替换旧数据,但会根据新长度影响行长度,有时会替换,但通常会追加。 单击此jsfiddle上的“运行”,直到看到ID出现一个较小的数字(例如“ 7”)。 然后按更新按钮,您将看到新数据不会更新行,而是根据新数组中的数字将其追加到行中。 因此,如果下一个数组恰好有8,那么您将看到一个8。如果以下数组有10,那么您将看到两个十。 我敢肯定,一旦修复此问题,它也将修复SVG动画。

具有三个“更新”的表的屏幕截图

这是我正在使用的通用代码。

// create table, etc.
var table = d3.select('.chart').append('table');
var thead = table.append('thead');
var tbody = table.append('tbody');

// append the header row
thead.append('tr')
    .selectAll('th')
    .data(['id','val','svg']).enter()
    .append('th')
    .text(function (col_names) { return col_names; });

function update_table(){

  data = newdata(); // update data to display

  // remove existing rows
  // this basically resets the table element
  // but is not the right way
  //tbody.selectAll('tr').remove();

  // join new data with old elements, if any
  var rows = tbody.selectAll('tr')
        .data(data)
        .enter()
        .append('tr');

  // add first two columns
  rows.append('td').text(function(d) { return d.id; })
  rows.append('td').text(function(d) { return d.val; });  

  // add svg
  var svgcell = rows.append('td')
    .append('svg')
      .attr("width",20)
      .attr("height",20);  
  svgcell.append('circle').transition().duration(500)
    .attr("cx", 10)
    .attr("cy", 10)
    .attr("r", function(d) { return d.val; })
    .style("fill", "red");

   tbody.selectAll('tr').data(data).exit().remove();  
}

对于D3代码,您的要求有点不寻常:您想根据数据更新行,但又不想删除包含圆圈的<td> ……这排除了最简单的解决方案,正在根据值列定义数据绑定功能的键功能

var rows = tbody.selectAll('tr')
    .data(data, function(d) {
        return d.val
    });

有了这个简单的解决方法,我在这里的解决方案就有点尴尬了。

首先,设置更新选择:

var rows = tbody.selectAll('tr')
    .data(data);

然后输入选择:

var rowsEnter = rows.enter()
    .append('tr');

rowsEnter.append('td')
    .attr("class", "idColumn")
    .text(function(d) {
        return d.id;
    });
rowsEnter.append('td')
    .attr("class", "valColumn")
    .text(function(d) {
        return d.val;
    });

rowsEnter.append('td')
    .append('svg')
    .attr("width", 20)
    .attr("height", 20).append('circle')
    .attr("class", "svgCircle")
    .style("fill", "red");

现在,按类选择所有列,重新绑定数据(这是我之前提到的笨拙的部分),并为圆设置过渡:

d3.selectAll(".idColumn").data(data).text(function(d) {
    return d.id;
});
d3.selectAll(".valColumn").data(data).text(function(d) {
    return d.val;
});
d3.selectAll(".svgCircle").data(data).attr("cx", 10)
    .attr("cy", 10).transition().duration(500)
    .attr("r", function(d) {
        return d.val;
    })
    .style("fill", "red");

最后,退出选择:

rows.exit().remove(); 

这是演示:

 // D3 update data, number rows in html table, animate svgs in last column function newdata() { var n = []; var r = Math.ceil(Math.random() * 20); for (var i = 0; i < r; i++) { n.push({ "id": r, "val": Math.random() * 10 }); } return n; } var data = newdata(); // generate data array of random length // create table, etc. var table = d3.select('.chart').append('table'); var thead = table.append('thead'); var tbody = table.append('tbody'); // append the header row thead.append('tr') .selectAll('th') .data(['id', 'val', 'svg']).enter() .append('th') .text(function(col_names) { return col_names; }); // update function function update_table() { // update data to display data = newdata(); // remove existing rows // this basically resets the table element // but is not the right way //tbody.selectAll('tr').remove(); // join new data with old elements, if any var rows = tbody.selectAll('tr') .data(data); var rowsEnter = rows.enter() .append('tr'); rowsEnter.append('td') .attr("class", "idColumn") .text(function(d) { return d.id; }); rowsEnter.append('td') .attr("class", "valColumn") .text(function(d) { return d.val; }); rowsEnter.append('td') .append('svg') .attr("width", 20) .attr("height", 20).append('circle') .attr("class", "svgCircle") .style("fill", "red"); d3.selectAll(".idColumn").data(data).text(function(d) { return d.id; }); d3.selectAll(".valColumn").data(data).text(function(d) { return d.val; }); d3.selectAll(".svgCircle").data(data).attr("cx", 10) .attr("cy", 10).transition().duration(500) .attr("r", function(d) { return d.val; }) .style("fill", "red"); rows.exit().remove(); } update_table(); var button = document.getElementById("update"); button.addEventListener("click", function(e) { update_table(); }); 
 <script src="https://d3js.org/d3.v4.min.js"></script> <button id="update">update</button> <div class="chart"></div> 

如果您更喜欢小提琴,这里是: https : //jsfiddle.net/evzx2x6L/

不确定这是否是正确的方法,但是我在调​​用update函数后1秒钟应用了transform属性,从而用D3为svgs设置了动画,并且可以正常工作。

 // D3 update data, number rows in html table, animate svgs in last column function newdata(){ var n = []; var r = Math.floor(Math.random() * 20); for (var i=0; i<r; i++){ n.push({ "id": i, "val": Math.random() * 10 }); } return n; } var data = newdata(); // generate data array of random length // create table, etc. var table = d3.select('.chart').append('table'); var thead = table.append('thead'); var tbody = table.append('tbody'); // append the header row thead.append('tr') .selectAll('th') .data(['id','val','svg']).enter() .append('th') .text(function (col_names) { return col_names; }); // update function function update_table(){ // update data to display data = newdata(); // remove existing rows // this basically resets the table element // but is not the right way tbody.selectAll('tr').remove(); // join new data with old elements, if any var rows = tbody.selectAll('tr') .data(data) .enter() .append('tr'); // add first two columns rows.append('td').text(function(d) { return d.id; }) rows.append('td').text(function(d) { return d.val; }); // add svg var svgcell = rows.append('td') .append('svg') .attr("width",20) .attr("height",20); svgcell.append('circle') .attr("cx", 10) .attr("cy", 10) .attr("r", function(d) { return d.val; }) .style("fill", "red"); tbody.selectAll('tr').data(data).exit().remove(); } update_table(); var button = document.getElementById("update"); button.addEventListener("click",function(e){ update_table(); setTimeout(function(){ document.querySelectorAll("circle").forEach(function(e){ d3.select(e) .attr("transform", "scale(0)") .transition() .duration(400) .attr("transform", "scale(1)") }); },10); }); 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <button id="update">update</button> <div class="chart"></div> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM