Javascript 从D3V3改编到v5的代码需要额外的更新才能正确呈现

Javascript 从D3V3改编到v5的代码需要额外的更新才能正确呈现,javascript,d3.js,Javascript,D3.js,当我尝试将代码从使用D3v3的版本改编到新版本D3v5时,我发现了一些问题 第一次执行时,图表显示不正确,但是,调用函数changeData更新两次后,图表将正确显示。在D3V3中,图表是直接向上显示的。我做错了什么 以下是显示错误的演示: let; 让半径; 让馅饼; 让弧; 让我们一起出去; 准备好数据; 切片; 宽度=700,高度=400; 让dataChart=[]; svg=d3。选择(“.chart-d3”) .append(“svg”) .附加(“g”); 半径=数学最小值(宽度

当我尝试将代码从使用D3v3的版本改编到新版本D3v5时,我发现了一些问题

第一次执行时,图表显示不正确,但是,调用函数
changeData
更新两次后,图表将正确显示。在D3V3中,图表是直接向上显示的。我做错了什么

以下是显示错误的演示:

let;
让半径;
让馅饼;
让弧;
让我们一起出去;
准备好数据;
切片;
宽度=700,高度=400;
让dataChart=[];
svg=d3。选择(“.chart-d3”)
.append(“svg”)
.附加(“g”);
半径=数学最小值(宽度、高度)/2.5;
append(“g”).attr(“类”、“切片”).attr(“名称”、“切片”);
svg.append(“g”).attr(“类”、“标签”);
svg.append(“g”).attr(“类”、“行”);
pie=d3.pie()
.sort(空)
.价值(功能(d){
返回d值;
});
弧=d3.arc()
.外表面(半径*0.8)
.内半径(半径*0.4);
outerArc=d3.arc()
.内半径(半径*0.9)
.外层(半径*0.9);
attr(“transform”、“translate”(+width/2+)、“+height/2+”);
让键=函数(d){
返回d.data.label;
}
var color=d3.scaleOrdinal()
.domain([“Lorem ipsum”、“dolor sit”、“amet”、“Concetetur”、“Adipising”、“elit”、“sed”、“do”、“eiusmod”、“Temporal”、“IncidUnt”])
.范围([“98abc5”、“8a89a6”、“7b6888”、“6b486b”、“a05d56”、“d0743c”、“ff8c00”);
函数randomData(){
让labels=color.domain();
让dataFor=labels.map(函数(标签){
返回{label:label,value:Math.random()}
});
将数据返回给;
}
changeData(randomData());
函数更改数据(数据){
数据准备就绪=饼图(数据);
slice=svg.select(“.slices”).selectAll(“path.slice”).data(data\u ready,key);
片
.输入()
.append('路径')
.style('fill',函数(d){返回颜色(d.data.label)})
.attr(“类”、“切片”);
片
.transition().持续时间(1000)
.attrTween(“d”,函数(d){
这个。|电流=这个。|电流| d;
var interpolate=d3.interpolate(该电流,d);
这是。_current=interpolate();
返回函数(t){
返回弧(插值(t));
};
})   
slice.exit()
.remove();
/*----文本标签-------*/
var text=svg。选择(“.labels”)。选择全部(“文本”)
.数据(数据准备就绪,键);
text.enter()
.append(“文本”)
.attr(“dy”,“.35em”)
.文本(功能(d){
返回d.data.label+“(“+Math.round(d.data.value*1000)+”);
});
text.transition().持续时间(1000)
.attrTween(“转换”,函数(d){
这个。|电流=这个。|电流| d;
设插值=d3.插值(该电流,d);
该值为._电流=插值(0);
返回函数(t){
设d2=插值(t);
设pos=外表面质心(d2);
位置[0]=半径*(中间角(d)
.chart-d3{
高度:400px;
宽度:700px;
边距:10px自动;方框阴影:1px 1px 10px 3px灰色;
显示器:flex;
弯曲方向:立柱;
}
svg{
宽度:100%;
身高:100%;
}
路径切片{
笔画宽度:2px;
}
多段线{
不透明度:.3;
笔画:黑色;
笔画宽度:2px;
填充:无;
}
钮扣{
高度:40px;
}

更新

从D3v4起,常规更新模式的行为已更改。从:

不再将进入的节点合并到更新选择中;用于在数据联接后组合输入和更新

这就是为什么你的图形在第一次跑步时被破坏的原因;新输入的图元不会被选中,因此不会转换到其最终位置。这将在第二次运行期间修复,因为这些相同的元素都将是更新选择的一部分

而不是做

slice = svg.select(".slices").selectAll("path.slice").data(data_ready, key);
slice
  .enter()
  .append('path')
  .style('fill', function(d){ return color(d.data.label) })
  .attr("class", "slice");

slice   // <-- This is just the update selection without newly entered elements
  .transition().duration(1000)

更新
slice = svg.select(".slices").selectAll("path.slice").data(data_ready, key);
slice = slice     // <══ 2. Store in update selection ══════════════════════╗
  .enter()                                                               // ║
  .append('path')                                                        // ║
  .style('fill', function(d){ return color(d.data.label) })              // ║
  .attr("class", "slice")                                                // ║
  .merge(slice);  // ═══ 1. Merge update selection into enter selection ════╝

slice   // <-- Now, this holds both entered as well as updated elements.
  .transition().duration(1000)