D3.js D3多个饼图更新

D3.js D3多个饼图更新,d3.js,pie-chart,D3.js,Pie Chart,我对D3非常陌生,但一直在研究一些示例,但在尝试更新多个饼图时遇到了一个问题。我可以从我的数据数组生成这些数据,但是当我想更新它们时,我遇到了一个问题 问题很简单,但我有点被困在如何解决这个问题上。我已经在js fiddle中运行了我的代码。您将看到,在我的示例中,我构建了三个Pie,然后等待3秒钟并将其更新为新数据。我的问题是,所有的馅饼似乎总是用相同的数据更新 我相信这是由于我选择路径以更新饼图的方式造成的。看起来我每次都在用每个数据数组更新每个路径,所以它们最终都会用数组中的最后一个数据集

我对D3非常陌生,但一直在研究一些示例,但在尝试更新多个饼图时遇到了一个问题。我可以从我的数据数组生成这些数据,但是当我想更新它们时,我遇到了一个问题

问题很简单,但我有点被困在如何解决这个问题上。我已经在js fiddle中运行了我的代码。您将看到,在我的示例中,我构建了三个Pie,然后等待3秒钟并将其更新为新数据。我的问题是,所有的馅饼似乎总是用相同的数据更新

我相信这是由于我选择路径以更新饼图的方式造成的。看起来我每次都在用每个数据数组更新每个路径,所以它们最终都会用数组中的最后一个数据集更新

如果有人知道我如何更新此文件以正确构建PIE,我将非常感谢任何帮助、指点或评论

var data = [
  [3, 4, 5, 9],
  [1, 7, 3, 4],
  [4, 3, 2, 1],
];


function getData() {
    // Generate some random data to update the pie with
    tdata = []
    for(i in data) {
        rdata = []
        for(c in data[i]) {
            rdata.push(Math.floor((Math.random() * 10) + 1) )
        }
        tdata.push(rdata)
    }
    return tdata
}

// ------------

var m = 10,
    r = 100

var mycolors = ["red","#FF7F00","#F5CC11","#D61687","#1E93C1","#64B72D","#999999"]

var arc = d3.svg.arc()
            .innerRadius(r / 2)    
            .outerRadius(r)

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

var svg = d3.select("body").selectAll("svg")
    .data(data)
    .enter()
        .append("svg")
        .attr("width", (r + m) * 2)
        .attr("height", (r + m) * 2)
        .attr("id", function(d,i) {return 'pie'+i;})
        .append("svg:g")
            .attr("transform", "translate(" + (r + m) + "," + (r + m) + ")");

var path = svg.selectAll("path")
    .data(pie)
    .enter()
        .append("svg:path")
        .attr("d", arc)
        .style("fill", function(d, i) { return mycolors[i]; })
        .each(function(d) { this._current = d; }); // store the initial angles

var titles = svg.append("svg:text") 
    .attr("class", "title") 
    .text(function(d,i) {return i;}) 
    .attr("dy", "5px")  
    .attr("text-anchor", "middle") 


// -- Do the updates
//------------------------
setInterval(function() {
  change()
}, 3000);


function change() {
    // Update the Pie charts with random data
    piedata = getData()
    svg.each(function(d,i) {
        path = path.data(pie(piedata[i]))
        path.transition().duration(1000).attrTween("d", arcTween); 
        })
    // temp, print new array to screen
    tdata = ""
    for(x in piedata) {
        tdata += "<strong>"+x+":</strong> "+piedata[x]+"<br>"
    }
    $('#pieData').html(tdata)
}

function arcTween(a) {
  var i = d3.interpolate(this._current, a);
  this._current = i(0);
  return function(t) {
    return arc(i(t));
  };
}
var数据=[
[3, 4, 5, 9],
[1, 7, 3, 4],
[4, 3, 2, 1],
];
函数getData(){
//生成一些随机数据以更新饼图
tdata=[]
对于(数据中的i){
rdata=[]
对于(数据[i]中的c){
数据推送(数学地板((数学随机()*10)+1))
}
数据推送(rdata)
}
返回数据
}
// ------------
var m=10,
r=100
var mycolors=[“红色”、“FF7F00”、“F5CC11”、“D61687”、“1E93C1”、“64B72D”、“99999”]
var arc=d3.svg.arc()
.内半径(r/2)
.外层(r)
var pie=d3.layout.pie()
.value(函数(d){返回d;})
.sort(空);
var svg=d3.选择(“主体”).选择全部(“svg”)
.数据(数据)
.输入()
.append(“svg”)
.attr(“宽度”(r+m)*2)
.attr(“高度”(r+m)*2)
.attr(“id”,函数(d,i){return'pie'+i;})
.append(“svg:g”)
.attr(“转换”、“平移”(“+(r+m)+”,“+(r+m)+”);
var path=svg.selectAll(“路径”)
.数据(pie)
.输入()
.append(“svg:path”)
.attr(“d”,弧)
.style(“fill”,函数(d,i){return mycolors[i];})
.each(函数(d){this._current=d;});//存储初始角度
var titles=svg.append(“svg:text”)
.attr(“类别”、“头衔”)
.text(函数(d,i){return i;})
.attr(“dy”,“5px”)
.attr(“文本锚定”、“中间”)
//--进行更新
//------------------------
setInterval(函数(){
更改()
}, 3000);
函数更改(){
//使用随机数据更新饼图
piedata=getData()
svg.each(函数(d,i){
path=path.data(pie(piedata[i]))
path.transition().duration(1000).attrTween(“d”,arcTween);
})
//临时,将新阵列打印到屏幕
tdata=“”
对于(数据中的x){
tdata+=“”+x+”:“+piedata[x]+”
” } $('#pieData').html(tdata) } 函数arcTween(a){ var i=d3.内插(该电流为a); 该电流=i(0); 返回函数(t){ 返回弧(i(t)); }; }
是的,我终于找到了这个解决方案,我正在发布这个解决方案,以防其他人也尝试做同样的事情

我认为这可能不是最好的,也不是最有效的方法,但这将是我需要的(在这一点上)。但如果有人还有更好的解决方案,那就很高兴听到你的消息

最后,我根据一个唯一的id选择了路径,我给了我创建的各个SVG元素,然后只更新了这些路径。现在我这样说听起来很简单,但确实让我难堪了一段时间

function change() {
    // Update the Pie charts with random data
    var newdata = getData()
    for(x in newdata) {
        var npath = d3.select("#pie"+x).selectAll("path").data(pie(newdata[x]))
        npath.transition().duration(1000).attrTween("d", arcTween); // redraw the arcs
    }
}
完整的工作副本可在