[英]d3 donut chart arc retrieves wrong data
I have a d3 donut chart with two arcs, the main arc edge retrieves wrong data to d
object on mouse over. 我有一个带有两个弧的d3甜甜圈图,主弧边缘在鼠标悬停时将错误的数据检索到d
对象。 Rest all areas in the arc shows correct data in log. 弧中的所有其余区域在日志中显示正确的数据。
The colored area has value 70
and the other arc with 30
. 着色区域的值为70
,另一个弧的值为30
。 The colored main arc edge shows data of the second arc (30). 彩色主弧边缘显示第二弧(30)的数据。
// data
var dataset = [{
color: "#5FC5EA",
value: 70
}, {
color: "transparent",
value: 30
}];
// size
var width = 460, z
height = 300,
radius = Math.min(width, height) / 2;
var pie = d3.layout.pie()
.sort(null).value(function(d) {
return d.value;
});
// thin arc
var arc1 = d3.svg.arc()
.innerRadius(radius - 20)
.outerRadius(radius - 11);
// main arc
var arc = d3.svg.arc()
.innerRadius(radius - 16)
.outerRadius(radius - 17);
// set svg
var svg = d3.select("#d3-setup-donut").append("svg")
.attr("class",'donut-chart')
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")")
.on('mouseout', function() {
d3.selectAll('.donut-tooltip').style('display','none');
});
// tooltip
var div = d3.select("body")
.append("div")
.attr("class", "donut-tooltip");
// draw thinner arc
var path = svg.selectAll(".background")
.data(pie([{
color: "#222427",
value: 1
}]))
.enter().append("path")
.attr("class", "background")
.attr("fill", function(d, i) {
return d.data.color;
})
.attr("d", arc1)
.on('click', function(d, i) {
//
})
.on("mousemove",function(d, i) {
var mouseVal = d3.mouse(this);
div.style("display","none");
div.html(d.data.label+" : "+d.value)
.style("left", (d3.event.pageX-40) + "px")
.style("top", (d3.event.pageY-35) + "px")
.style("opacity", 1)
.style("display","block");
})
.on("mouseout",function(){
div.html(" ").style("display","none");
});
// draw main arc
var path = svg.selectAll(".foreground")
.data(pie(dataset))
.enter().append("path")
.attr("class", "foreground")
//.attr("stroke-linejoin", "round")
//.attr("stroke-linecap", "round")
.attr("stroke-width", "20")
.attr("stroke","none")
.attr("stroke", function(d, i) {
return d.data.color;
})
.attr("fill", "none")
.attr("d", arc)
.on('click', function(d, i) {
//
})
.on("mousemove",function(d, i) {
console.log(d)
var mouseVal = d3.mouse(this);
div.style("display","none");
div.html(d.data.label+" : "+d.value)
.style("left", (d3.event.pageX-40) + "px")
.style("top", (d3.event.pageY-35) + "px")
.style("opacity", 1)
.style("display","block");
})
.on("mouseout",function(){
div.html(" ").style("display","none");
});
// draw inner text
svg.append("text")
.text('60%')
.attr("class", "donut-inner-val")
//.attr("x", radius/12 - 30)
//.attr("y", radius/12 - 10);
svg.append("text")
.text('in progress')
.attr("class", "donut-inner-text")
.attr("x", (radius/12) - 35)
.attr("y", (radius/12) + 10);
Your problem is being caused by the stroke-width
attribute. 您的问题是由stroke-width
属性引起的。 What happens is this: the stroke width doesn't just add pixels to the sides of the arc, it add pixels to its end as well. 这是发生了什么:笔触宽度不仅在弧的两侧添加了像素,还在其末端添加了像素。
We can see this in the following demo, exaggerating the stroke width and colouring the transparent path (I also changed the opacity, so you can see where each path ends): 我们可以在下面的演示中看到这一点,放大了笔触宽度并为透明路径着色(我还更改了不透明度,因此您可以看到每个路径的结束位置):
// data var dataset = [{ color: "#5FC5EA", value: 70 }, { color: "red", value: 30 }]; // size var width = 460, z height = 300, radius = Math.min(width, height) / 2; var pie = d3.layout.pie() .sort(null).value(function(d) { return d.value; }); // thin arc var arc1 = d3.svg.arc() .innerRadius(radius - 20) .outerRadius(radius - 11); // main arc var arc = d3.svg.arc() .innerRadius(radius - 16) .outerRadius(radius - 17); // set svg var svg = d3.select("#d3-setup-donut").append("svg") .attr("class", 'donut-chart') .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") .on('mouseout', function() { d3.selectAll('.donut-tooltip').style('display', 'none'); }); // tooltip var div = d3.select("body") .append("div") .attr("class", "donut-tooltip"); // draw thinner arc var path = svg.selectAll(".background") .data(pie([{ color: "#222427", value: 1 }])) .enter().append("path") .attr("class", "background") .attr("fill", function(d, i) { return d.data.color; }) .attr("d", arc1) .on('click', function(d, i) { // }) .on("mousemove", function(d, i) { var mouseVal = d3.mouse(this); div.style("display", "none"); div.html(d.data.label + " : " + d.value) .style("left", (d3.event.pageX - 40) + "px") .style("top", (d3.event.pageY - 35) + "px") .style("opacity", 1) .style("display", "block"); }) .on("mouseout", function() { div.html(" ").style("display", "none"); }); // draw main arc var path = svg.selectAll(".foreground") .data(pie(dataset)) .enter().append("path") .attr("class", "foreground") //.attr("stroke-linejoin", "round") //.attr("stroke-linecap", "round") .attr("stroke-width", (d,i)=>60 - i*10) .attr("opacity", (d,i)=> 1 - i*0.2) .attr("stroke", "none") .attr("stroke", function(d, i) { return d.data.color; }) .attr("fill", "none") .attr("d", arc) .on('click', function(d, i) { // }) .on("mousemove", function(d, i) { var mouseVal = d3.mouse(this); div.style("display", "none"); div.html(d.data.label + " : " + d.value) .style("left", (d3.event.pageX - 40) + "px") .style("top", (d3.event.pageY - 55) + "px") .style("opacity", 1) .style("display", "block"); }) .on("mouseout", function() { div.html(" ").style("display", "none"); }); // draw inner text svg.append("text") .text('60%') .attr("class", "donut-inner-val") //.attr("x", radius/12 - 30) //.attr("y", radius/12 - 10); svg.append("text") .text('in progress') .attr("class", "donut-inner-text") .attr("x", (radius / 12) - 35) .attr("y", (radius / 12) + 10);
$pale-blue: #f6f8fe; $dark-two:#253644; $pale-grey: #f0f4f7; $font-roman:'Helvetica LT W01 Roman'; $font-light:'Helvetica LT W01 Light'; $font-bold:'Helvetica LT W01 Bold'; body { background-color:#25333F; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } .donut-inner-val{ text-anchor:middle; font-family: $font-light; font-size: 24px; fill:$pale-blue; } .donut-inner-text { font-family: $font-light; font-size: 10px; fill:$pale-blue; } .background { z-index:1; } .foreground { z-index:2; } .foreground, .background { cursor:pointer; } .donut-tooltip{ line-height: 1; font-weight: normal; padding: 10px 5px; background: #ccc; border-color:#ccc; //opacity:.5; color: #333; border-radius: 2px; font-size:11px; position: absolute; text-align: center; height: 28px; opacity:0; z-index:99999; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="d3-setup-donut" style="margin:30px auto;"></div>
As you can see, the red path is overlapping the blue path. 如您所见,红色路径与蓝色路径重叠。
Solution : change the inner and outer radii, and paint the paths using fill
, not stroke
: 解决方案 :更改内部和外部半径,并使用fill
而不是stroke
绘制路径:
// data var dataset = [{ color: "#5FC5EA", value: 70 }, { color: "transparent", value: 30 }]; // size var width = 460, z height = 300, radius = Math.min(width, height) / 2; var pie = d3.layout.pie() .sort(null).value(function(d) { return d.value; }); // thin arc var arc1 = d3.svg.arc() .innerRadius(radius - 20) .outerRadius(radius - 11); // main arc var arc = d3.svg.arc() .innerRadius(radius - 30) .outerRadius(radius); // set svg var svg = d3.select("#d3-setup-donut").append("svg") .attr("class", 'donut-chart') .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") .on('mouseout', function() { d3.selectAll('.donut-tooltip').style('display', 'none'); }); // tooltip var div = d3.select("body") .append("div") .attr("class", "donut-tooltip"); // draw thinner arc var path = svg.selectAll(".background") .data(pie([{ color: "#222427", value: 1 }])) .enter().append("path") .attr("class", "background") .attr("fill", function(d, i) { return d.data.color; }) .attr("d", arc1) .on('click', function(d, i) { // }) .on("mousemove", function(d, i) { var mouseVal = d3.mouse(this); div.style("display", "none"); div.html(d.data.label + " : " + d.value) .style("left", (d3.event.pageX - 40) + "px") .style("top", (d3.event.pageY - 35) + "px") .style("opacity", 1) .style("display", "block"); }) .on("mouseout", function() { div.html(" ").style("display", "none"); }); // draw main arc var path = svg.selectAll(".foreground") .data(pie(dataset)) .enter().append("path") .attr("class", "foreground") //.attr("stroke-linejoin", "round") //.attr("stroke-linecap", "round") .attr("stroke-width", "1") .attr("stroke", "none") .attr("fill", function(d, i) { return d.data.color; }) .attr("d", arc) .on('click', function(d, i) { // }) .on("mousemove", function(d, i) { var mouseVal = d3.mouse(this); div.style("display", "none"); div.html(d.data.label + " : " + d.value) .style("left", (d3.event.pageX - 40) + "px") .style("top", (d3.event.pageY - 55) + "px") .style("opacity", 1) .style("display", "block"); }) .on("mouseout", function() { div.html(" ").style("display", "none"); }); // draw inner text svg.append("text") .text('60%') .attr("class", "donut-inner-val") //.attr("x", radius/12 - 30) //.attr("y", radius/12 - 10); svg.append("text") .text('in progress') .attr("class", "donut-inner-text") .attr("x", (radius / 12) - 35) .attr("y", (radius / 12) + 10);
$pale-blue: #f6f8fe; $dark-two:#253644; $pale-grey: #f0f4f7; $font-roman:'Helvetica LT W01 Roman'; $font-light:'Helvetica LT W01 Light'; $font-bold:'Helvetica LT W01 Bold'; body { background-color:#25333F; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } .donut-inner-val{ text-anchor:middle; font-family: $font-light; font-size: 24px; fill:$pale-blue; } .donut-inner-text { font-family: $font-light; font-size: 10px; fill:$pale-blue; } .background { z-index:1; } .foreground { z-index:2; } .foreground, .background { cursor:pointer; } .donut-tooltip{ line-height: 1; font-weight: normal; padding: 10px 5px; background: #ccc; border-color:#ccc; //opacity:.5; color: #333; border-radius: 2px; font-size:11px; position: absolute; text-align: center; height: 28px; opacity:0; z-index:99999; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="d3-setup-donut" style="margin:30px auto;"></div>
This is the same code, but painting the transparent path as red. 这是相同的代码,但是将透明路径绘制为红色。 Now, you can see that it ends at the correct end angle: 现在,您可以看到它以正确的结束角度结束:
// data var dataset = [{ color: "#5FC5EA", value: 70 }, { color: "red", value: 30 }]; // size var width = 460, z height = 300, radius = Math.min(width, height) / 2; var pie = d3.layout.pie() .sort(null).value(function(d) { return d.value; }); // thin arc var arc1 = d3.svg.arc() .innerRadius(radius - 20) .outerRadius(radius - 11); // main arc var arc = d3.svg.arc() .innerRadius(radius - 30) .outerRadius(radius); // set svg var svg = d3.select("#d3-setup-donut").append("svg") .attr("class", 'donut-chart') .attr("width", width) .attr("height", height) .append("g") .attr("transform", "translate(" + width / 2 + "," + height / 2 + ")") .on('mouseout', function() { d3.selectAll('.donut-tooltip').style('display', 'none'); }); // tooltip var div = d3.select("body") .append("div") .attr("class", "donut-tooltip"); // draw thinner arc var path = svg.selectAll(".background") .data(pie([{ color: "#222427", value: 1 }])) .enter().append("path") .attr("class", "background") .attr("fill", function(d, i) { return d.data.color; }) .attr("d", arc1) .on('click', function(d, i) { // }) .on("mousemove", function(d, i) { var mouseVal = d3.mouse(this); div.style("display", "none"); div.html(d.data.label + " : " + d.value) .style("left", (d3.event.pageX - 40) + "px") .style("top", (d3.event.pageY - 35) + "px") .style("opacity", 1) .style("display", "block"); }) .on("mouseout", function() { div.html(" ").style("display", "none"); }); // draw main arc var path = svg.selectAll(".foreground") .data(pie(dataset)) .enter().append("path") .attr("class", "foreground") //.attr("stroke-linejoin", "round") //.attr("stroke-linecap", "round") .attr("stroke-width", "1") .attr("stroke", "none") .attr("fill", function(d, i) { return d.data.color; }) .attr("d", arc) .on('click', function(d, i) { // }) .on("mousemove", function(d, i) { var mouseVal = d3.mouse(this); div.style("display", "none"); div.html(d.data.label + " : " + d.value) .style("left", (d3.event.pageX - 40) + "px") .style("top", (d3.event.pageY - 55) + "px") .style("opacity", 1) .style("display", "block"); }) .on("mouseout", function() { div.html(" ").style("display", "none"); }); // draw inner text svg.append("text") .text('60%') .attr("class", "donut-inner-val") //.attr("x", radius/12 - 30) //.attr("y", radius/12 - 10); svg.append("text") .text('in progress') .attr("class", "donut-inner-text") .attr("x", (radius / 12) - 35) .attr("y", (radius / 12) + 10);
$pale-blue: #f6f8fe; $dark-two:#253644; $pale-grey: #f0f4f7; $font-roman:'Helvetica LT W01 Roman'; $font-light:'Helvetica LT W01 Light'; $font-bold:'Helvetica LT W01 Bold'; body { background-color:#25333F; font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; } .donut-inner-val{ text-anchor:middle; font-family: $font-light; font-size: 24px; fill:$pale-blue; } .donut-inner-text { font-family: $font-light; font-size: 10px; fill:$pale-blue; } .background { z-index:1; } .foreground { z-index:2; } .foreground, .background { cursor:pointer; } .donut-tooltip{ line-height: 1; font-weight: normal; padding: 10px 5px; background: #ccc; border-color:#ccc; //opacity:.5; color: #333; border-radius: 2px; font-size:11px; position: absolute; text-align: center; height: 28px; opacity:0; z-index:99999; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script> <div id="d3-setup-donut" style="margin:30px auto;"></div>
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.