D3.js D3:如何用新数据刷新图表?

D3.js D3:如何用新数据刷新图表?,d3.js,D3.js,我已经创建了一个d3甜甜圈图表。这是我的密码: var width = 480; var height = 480; var radius = Math.min(width, height) / 2; var doughnutWidth = 30; var color = d3.scale.category10(); var arc = d3.svg.arc() .outerRadius(radius - 10) .innerRadius(radius - 70); var pie = d

我已经创建了一个d3甜甜圈图表。这是我的密码:

var width = 480;
var height = 480;
var radius = Math.min(width, height) / 2;
var doughnutWidth = 30;

var color = d3.scale.category10();

var arc = d3.svg.arc()
.outerRadius(radius - 10)
.innerRadius(radius - 70);

var pie = d3.layout.pie()
.sort(null)
.value(function(d) { return d[1]; });

var dataset = settings.dataset;
console.log(dataset);

var svg = d3.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");

var path = svg.selectAll('path')
.data(pie(dataset))
.enter()
.append('path')
.attr('d', arc)
.attr('fill', function(d, i) { 
  return color(d.data[0]);
})
我在我的网页上有一个简单的表单,它显示了一个带有多个选项的下拉菜单。每次用户更改表单上的值时,一个新的数据集就会发送到我的脚本(settings.dataset),并且甜甜圈会在页面上重新绘制

问题是,上一个数据集中的一些值仍保留在DOM中。在下面的控制台输出中,您可以看到第二个数据集只有两个元素。第三个来自上一个数据集。这会弄乱图表,因为它显示的是一个不应该存在的值


我的问题是:如何清除旧的价值观?我已经阅读了
.exit()
.remove()
,但是我无法理解这些方法。

有两个步骤来实现您想要的“重画”效果:

首先,我假设您希望在第一次加载页面时只绘制一次svg画布,然后更新svg中的图表,而不是删除并重新绘制svg:

 var svg = d3.select("body")
              .selectAll("svg")
              .data([settings.dataset]);  
 // put data in an array with only one element

 // this ensures there is only one consistent svg on the page when data is updated(when the script gets executed) 
 svg.enter().append("svg")  
第二,了解
enter()
exit()
,有很多关于这方面的优秀教程。在你的情况下,我建议画这样的甜甜圈:

var path = svg.selectAll(".donut")  
           .data(settings.data)

// bind data to elements, now you have elements belong to one of those 
// three 'states', enter, exit, or update

// for `enter` selection, append elements
path.enter().append("path").attr("d", arc).attr("fill", "teal")

// for `update` selection, which means they are already binded with data
path.transition().attrTween("d", someFunction) // apply transition here if you want some animation for data change

// for `exit` selection, they shouldn't be on the svg canvas since there is no corresponding data, you can then remove them
 path.exit().remove()
创建一个函数,在创建和更新饼图时(重新)绘制饼图

应使用
enter()
将新数据添加到饼图中,并使用
exit()删除旧数据。删除()

就这么简单:

  path.enter().append("path")
            .attr("fill", function(d, i) { return color(i); })
            .attr("d", arc)
            .each(function(d) {this._current = d;} );

  path.transition()
            .attrTween("d", arcTween);

  path.exit().remove()

完整的工作代码->

所以您上面粘贴的代码每次在udate上都会执行?是的,每次用户在我的表单上选择不同的选项时,脚本都会被调用。我看到的一个问题是d3.select(“body”).append(“svg”),这意味着您每次更新时都会追加svg。执行d3.select(“svg”).remove()以确保在更新时删除它。将该行添加到脚本顶部?这是一个非常好的教程:我接受你的观点:绘制一次图表,然后根据用户选择进行更新。有点像这样:。目前我只加载用户感兴趣的数据。在这种方法中,我需要加载所有数据并存储在一个更大的数组中——这不是一个大问题,因为数据量很小。我必须重写传递数据的代码。谢谢你的建议。我认为每次重新绘制图表会更适合我的用例。如果你的意思是每次删除并重新附加路径,那么transition()和exit()就不必了。在我问题的控制台输出中,第一个输出来自我的第一个油炸圈饼的绘制。这是正确的,有三个值。第二个输出是一个新的甜甜圈,它应该只有两个值(anonymous和johnd),但它包含第一个甜甜圈的第三个值Blog3。在绘制第二个甜甜圈之前,我需要删除此值。@24ma13wg看起来问题是由
设置引起的。dataset
,与d3绘图没有太大关系,请您添加更多关于如何获取
设置的代码。dataset
?每个
函数(d){this.\u current=d;})
做什么?
//remove and create svg
d3.select("svg").remove(); 
var svg = d3.select("body").append("svg").attr("width","960").attr("height", "600"),
inner = svg.append("g");