我正在尝试在d3js中创建一个甜甜圈图,其中每个弧的末端都有一个圆。
圆的边缘必须适合圆弧的边缘。
我尝试通过附加一个圆和一个用标记包裹但没有成功的圆来进行尝试。
尝试添加标记似乎是最接近所需标记的解决方案,但我无法帮助标记溢出弧形边缘。
码:
var data = [
{
name: "punti",
count: 3,
color: "#fff000"
},
{
name: "max",
count: 7,
color: "#f8b70a"
}
];
var totalCount = data.reduce((acc, el) => el.count + acc, 0);
var image_width = 32;
var image_height = 32;
var width = 540,
height = 540,
radius = 200,
outerRadius = radius - 10,
innerRadius = 100;
var cornerRadius = innerRadius;
var markerRadius = (outerRadius - innerRadius) / 2;
var arc = d3
.arc()
.outerRadius(outerRadius)
.innerRadius(innerRadius)
.cornerRadius(cornerRadius);
var pie = d3
.pie()
.sort(null)
.value(function(d) {
return d.count;
});
var svg = d3
.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var pieData = pie(data);
var g = svg
.selectAll(".arc")
.data(pieData)
.enter()
.append("g");
var path = g
.append("path")
.attr("d", arc)
.style("fill", function(d, i) {
return d.data.color;
});
var marker = svg
.append("defs")
.append("marker")
.attr("id", "endmarker")
.attr("overflow", "visible")
.append("circle")
.attr("cy", 0)
.attr("cx", 0)
.attr("r", markerRadius)
.attr("fill", "red");
g.attr("marker-end", "url(#endmarker)");
g
.append("circle")
.attr("cx", function(d) {
let path = d3.select(this.parentNode);
var x = arc.centroid(d)[0];
return x;
})
.attr("cy", function(d) {
var y = arc.centroid(d)[1];
console.log(d3.select(this).attr("cx"));
return y;
})
.attr("fill", d => d.data.color)
.attr("stroke", "black")
.attr("r", (outerRadius - innerRadius) / 2);
codepen here
感谢任何人的帮助!
最佳答案
假设您希望输出如下:
我从Mike Bostock's Block here which shows how to add circles to rounded Arc Corners找到了一些代码。
我为您改编了以下代码,该代码执行了很多复杂的数学运算。
var cornerRadius = (outerRadius - innerRadius)/2;
svg.append("g")
.style("stroke", "#555")
.style("fill", "none")
.attr("class", "corner")
.selectAll("circle")
.data(d3.merge(pieData.map(function(d) {
return [
{angle: d.startAngle + d.padAngle / 2, radius: outerRadius - cornerRadius, start: +1},
{angle: d.endAngle - d.padAngle / 2, radius: outerRadius - cornerRadius, start: -1},
];
})))
.enter().append("circle")
.attr("cx", function(d) { return d.start * cornerRadius * Math.cos(d.angle) + Math.sqrt(d.radius * d.radius - cornerRadius * cornerRadius) * Math.sin(d.angle); })
.attr("cy", function(d) { return d.start * cornerRadius * Math.sin(d.angle) - Math.sqrt(d.radius * d.radius - cornerRadius * cornerRadius) * Math.cos(d.angle); })
.attr("r", cornerRadius);
完整的片段显示输出:
<div id="chart"></div>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.12.0/d3.min.js"></script>
<script>
var data = [
{
name: "punti",
count: 3,
color: "#fff000"
},
{
name: "max",
count: 7,
color: "#f8b70a"
},
];
var totalCount = data.reduce((acc, el) => el.count + acc, 0);
var image_width = 32;
var image_height = 32;
var width = 540,
height = 540,
radius = 200,
outerRadius = radius - 10,
innerRadius = 100;
var cornerRadius = innerRadius;
var markerRadius = (outerRadius - innerRadius) / 2;
var arc = d3
.arc()
.outerRadius(outerRadius)
.innerRadius(innerRadius)
.cornerRadius(cornerRadius);
var pie = d3
.pie()
.sort(null)
.value(function(d) {
return d.count;
});
var svg = d3
.select("body")
.append("svg")
.attr("width", width)
.attr("height", height)
.append("g")
.attr("transform", "translate(" + width / 2 + "," + height / 2 + ")");
var pieData = pie(data);
var g = svg
.selectAll(".arc")
.data(pieData)
.enter()
.append("g");
var path = g
.append("path")
.attr("d", arc)
.style("fill", function(d, i) {
return d.data.color;
});
var cornerRadius = (outerRadius - innerRadius)/2;
svg.append("g")
.style("stroke", "#555")
.style("fill", "none")
.attr("class", "corner")
.selectAll("circle")
.data(d3.merge(pieData.map(function(d) {
return [
{angle: d.startAngle + d.padAngle / 2, radius: outerRadius - cornerRadius, start: +1},
{angle: d.endAngle - d.padAngle / 2, radius: outerRadius - cornerRadius, start: -1},
];
})))
.enter().append("circle")
.attr("cx", function(d) { return d.start * cornerRadius * Math.cos(d.angle) + Math.sqrt(d.radius * d.radius - cornerRadius * cornerRadius) * Math.sin(d.angle); })
.attr("cy", function(d) { return d.start * cornerRadius * Math.sin(d.angle) - Math.sqrt(d.radius * d.radius - cornerRadius * cornerRadius) * Math.cos(d.angle); })
.attr("r", cornerRadius);
</script>
关于javascript - d3js:如何在圆弧的末端放置圆圈,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/59013408/