[英]D3 Pie chart initial render issue
查看實現 d3 餅圖,並且餅圖的初始繪制未正確呈現。 然而,一旦我調用重繪(隨機化左上角),它就會按預期落到位,然后未來的按預期過渡。
第一次初始化圖表時,我在這里做錯了什么嗎?
https://codepen.io/MattN96/pen/xxdVjRN
<!DOCTYPE html>
<meta charset="utf-8">
<style>
body {
font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
width: 960px;
height: 500px;
position: relative;
}
svg {
width: 100%;
height: 100%;
}
path.slice{
stroke-width:2px;
}
polyline{
opacity: .3;
stroke: black;
stroke-width: 2px;
fill: none;
}
</style>
<body>
<button class="randomize">randomize</button>
<script src="//cdnjs.cloudflare.com/ajax/libs/d3/5.9.2/d3.min.js" data-semver="5.9.2" data-require="d3@*"></script>
<script>
var arc, outerArc, width, height, radius;
var pie = d3.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var key = function(d){ return d.data.label; };
var color = d3.scaleOrdinal()
.domain(["Lorem ipsum", "dolor sit", "amet"])
.range(["#98abc5", "#6b486b", "#d0743c", "#ff8c00"]);
function randomData (){
var labels = ["Lorem ipsum", "dolor sit", "amet"];
return labels.map(function(label){
return { label: label, value: Math.random() }
});
}
initialRender(randomData());
redraw(randomData());
d3.select(".randomize")
.on("click", function(){
redraw(randomData());
});
function initialRender(data){
var svg = d3.select("body")
.append("svg")
.append("g")
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
width = 960;
height = 450;
radius = Math.min(width, height) / 2;
var pie = d3.pie()
.sort(null)
.value(function(d) {
return d.value;
});
arc = d3.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.4);
outerArc = d3.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
}
function redraw(data) {
var pieData = pie(data);
var svg = d3.select("body")
var text = svg.select(".labels").selectAll("text")
.data(pieData, key);
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
return d.data.label;
});
function midAngle(d){
return d.startAngle + (d.endAngle - d.startAngle)/2;
}
text.transition().duration(1000)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate("+ pos +")";
};
})
.styleTween("text-anchor", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start":"end";
};
});
text.exit()
.remove();
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pieData, key);
polyline.enter()
.append("polyline");
polyline.transition().duration(1000)
.attrTween("points", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});
polyline.exit()
.remove();
/* ------- PIE SLICES -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pieData, key);
slice.enter()
.insert("path")
.style("fill", function(d) { return color(d.data.label); })
.attr("class", "slice");
slice
.transition().duration(1000)
.attrTween("d", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
slice.exit()
.remove();
/* ------- TEXT LABELS -------*/
};
</script>
</body>
你很親近。 你的問題在這里:
text.transition().duration(1000)
對於折線和切片過渡也是如此。 在第一次渲染時,變量text
選擇的 dom 上沒有實際text
。 您隨后附加了文本,但附加不會改變您的原始選擇變量。 您需要在輸入后重新選擇每個,追加。 選擇 enter append 以后不起作用,因為以后的 enter append selections 將為空(您永遠不會添加任何新切片等)
var arc, outerArc, width, height, radius;
var pie = d3.pie()
.sort(null)
.value(function(d) {
return d.value;
});
var key = function(d){ return d.data.label; };
var color = d3.scaleOrdinal()
.domain(["Lorem ipsum", "dolor sit", "amet"])
.range(["#98abc5", "#6b486b", "#d0743c", "#ff8c00"]);
function randomData (){
var labels = ["Lorem ipsum", "dolor sit", "amet"];
return labels.map(function(label){
return { label: label, value: Math.random() }
});
}
initialRender(randomData());
redraw(randomData());
d3.select(".randomize")
.on("click", function(){
redraw(randomData());
});
function initialRender(data){
var svg = d3.select("body")
.append("svg")
.append("g")
svg.append("g")
.attr("class", "slices");
svg.append("g")
.attr("class", "labels");
svg.append("g")
.attr("class", "lines");
width = 960;
height = 450;
radius = Math.min(width, height) / 2;
var pie = d3.pie()
.sort(null)
.value(function(d) {
return d.value;
});
arc = d3.arc()
.outerRadius(radius * 0.8)
.innerRadius(radius * 0.4);
outerArc = d3.arc()
.innerRadius(radius * 0.9)
.outerRadius(radius * 0.9);
svg.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
}
function redraw(data) {
var pieData = pie(data);
var svg = d3.select("body")
var text = svg.select(".labels").selectAll("text")
.data(pieData, key);
text.enter()
.append("text")
.attr("dy", ".35em")
.text(function(d) {
return d.data.label;
});
var textPath= svg.selectAll('text')
function midAngle(d){
return d.startAngle + (d.endAngle - d.startAngle)/2;
}
textPath.transition().duration(1000)
.attrTween("transform", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * (midAngle(d2) < Math.PI ? 1 : -1);
return "translate("+ pos +")";
};
})
.styleTween("text-anchor", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
return midAngle(d2) < Math.PI ? "start":"end";
};
});
text.exit()
.remove();
/* ------- SLICE TO TEXT POLYLINES -------*/
var polyline = svg.select(".lines").selectAll("polyline")
.data(pieData, key);
polyline.enter()
.append("polyline");
var polyPath= svg.selectAll('polyline')
polyPath.transition().duration(1000)
.attrTween("points", function(d){
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
var d2 = interpolate(t);
var pos = outerArc.centroid(d2);
pos[0] = radius * 0.95 * (midAngle(d2) < Math.PI ? 1 : -1);
return [arc.centroid(d2), outerArc.centroid(d2), pos];
};
});
polyPath.exit()
.remove();
/* ------- PIE SLICES -------*/
var slice = svg.select(".slices").selectAll("path.slice")
.data(pieData, key);
slice.enter()
.insert("path")
.style("fill", function(d) { return color(d.data.label); })
.attr("class", "slice");
var slicePath = svg.selectAll('.slice')
slicePath
.transition().duration(1000)
.attrTween("d", function(d) {
this._current = this._current || d;
var interpolate = d3.interpolate(this._current, d);
this._current = interpolate(0);
return function(t) {
return arc(interpolate(t));
};
})
slice.exit()
.remove();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.