我创建了一个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()
,但我不能让我的头围绕这些方法.
创建一个函数(重新)在创建饼图时及其更新时绘制饼图.
应使用新数据添加到饼图中,enter()
并使用旧数据删除exit().remove()
这很简单:
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()
完整的工作代码 - > JSFIDDLE
实现所需的"重绘"效果有两个步骤:
首先,我想你希望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()