Проблема в том, что каждый раз, когда вызывается функция, вы добавляете новый элемент SVG с этой строкой:
var donutChart = d3.select(id).append('svg')
, так как при этом выбирается первый найденный элемент с идентификатором и добавляется новый элемент SVGнезависимо от того.
Вторая проблема возникает, когда вы пытаетесь добавить дуги с этой строкой
var arc_g = d3.select('svg g').selectAll('arc')
, как снова, "select" просто найдет первое совпадение в DOM, который является вашим исходным SVG> Элемент G, и выберите дуги, которые он может найти там
В-третьих, .selectAll('arc')
ничего не найдет, так как существующие элементы либо 'path', либо имеют класс 'slice', поэтому вам нуженвыберитеВсе для сопоставления с любым из них.
Чтобы устранить проблемы:
//append the SVG on the first call, with a dummy data, and each subsequent call will use the existing element in the DOM
var donutChart = d3.select(id).selectAll('svg')
.data([null])
donutChart = donutChart.enter().append('svg')
.merge(donutChart)
.attr('width', width)
.attr('height', height)
var g = donutChart.append('g')
.attr('transform', 'translate(' + (width - radius) + ',' + (height - radius) + ')');
var pie = d3.pie()
.sort(null)
.value(function(piedata) { return piedata.value; });
//selectAll on class '.slice'
var arc_g = g.selectAll('.slice')
.data(pie(piedata))
//create new g and path elements on enter (ie if new), and then update d and color after a merge()
arc_g = arc_g.enter()
.append('g')
.attr('class', 'slice')
.append('path')
.merge(arc_g)
.attr("d",arc)
.attr('fill', function(d, range) {
return colors(range);
})
Для получения дополнительной информации о слиянии см. https://github.com/d3/d3-selection#selection_merge