给出一个带有圆弧的饼图,我想在每个圆弧的中心点附加直线以遵循路径。我目前可以在路径上正确地附加线条,但不能适当地倾斜它们。我在饼图周围有一组圆,需要将这些线放置在圆的下方,在第一个圆与下一个圆之间的中点处。这是我要执行的操作的大致图像,线条应在圆弧的中心,但在圆的下方,并沿着圆弧的路径。
这是我当前使用代码获得的结果。我正在尝试使深黑色线条跟随与您在中心看到的浅灰色线条相似的旋转。
const startAngle = (-45 * Math.PI) / 180;
const endAngle = (-45 * Math.PI) / 180 + 2 * Math.PI;
const width = 500;
const height = Math.min(width, 500);
const viewBox = [-width / 2, -height / 2, width, height];
const svg = d3
.select("#canvas")
.append("svg")
.attr("viewBox", viewBox);
function drawGridDonut(svg, innerFactor, outerFactor) {
const radius = Math.min(width, height) / 2;
const graph = new Array(6); // 6 equal sections
const gridPie = d3
.pie()
.startAngle(startAngle)
.endAngle(endAngle)
.sort(null)
.value(1);
const arc = d3
.arc()
.innerRadius(radius * innerFactor)
.outerRadius(radius * outerFactor);
// base path + arc
svg
.append("g")
.attr("class", "grid")
.selectAll("path")
.data(gridPie(graph))
.join("path")
.attr("stroke-width", 1)
.attr("fill", "none")
.attr("d", arc);
// border lines
svg
.selectAll(".grid")
// border lines, 1 = dark border, 0 = light border
.data(gridPie([1, 0, 1, 0, 1, 0]))
.append("line")
.attr("x1", 0)
.attr("y1", 0)
.attr(
"y2",
d =>
Math.sin(d.startAngle - Math.PI / 2) *
(radius - (d.data === 1 ? 0 : 75.5))
)
.attr(
"x2",
d =>
Math.cos(d.startAngle - Math.PI / 2) *
(radius - (d.data === 1 ? 0 : 75.5))
)
.attr("stroke", d => (d.data === 0 ? "#C8C8C8" : "#000"))
.attr("stroke-width", "0.1");
// dots for overuse + benefits
svg
.selectAll(".dot")
.data(gridPie([...Array(12)]))
.enter()
.append("circle")
.attr('class', '.dot')
.attr("cx", d => arc.centroid(d)[0])
.attr("cy", d => arc.centroid(d)[1])
.attr("r", 1)
.style("fill", "#C8C8C8");
// this is where the lines are being made
svg
.selectAll('.hash')
.data(gridPie([...Array(12)]))
.enter()
.append('line')
.attr('class', '.hash')
.attr('d', arc)
.attr("x1", (d) => arc.centroid(d)[0] - d.startAngle)
.attr("y1", (d) => arc.centroid(d)[1] - d.startAngle)
.attr('x2', d => arc.centroid(d)[0] + d.endAngle )
.attr('y2', d => arc.centroid(d)[1] + d.endAngle)
.attr('width', 10)
.attr('height', 4)
.attr("stroke", "black")
.attr('transform', (d) => 'rotate(180)')
}
for (let i = 0; i < 6; i++) {
drawGridDonut(svg, 0.9 - 0.04, 0.9 + 0.002)
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/5.7.0/d3.min.js"></script>
<div id="canvas"></div>
答案 0 :(得分:0)
我通过在饼的中心到顶部绘制一条线,然后添加破折号数组(对内外圆弧进行微调以标记安全空间)来解决此问题。
function drawHyphen(svg, innerFactor, outerFactor, dashPercent) {
const radius = Math.min(width, height) / 2;
const gridPie = d3
.pie()
.startAngle(startAngle)
.endAngle(endAngle)
.sort(null)
.value(1);
svg
.selectAll('.line')
.data(gridPie([...Array(12)]))
.enter()
.append("line")
.attr('class', (d, i) => `line${i}`)
.attr(
"y1",
d =>
Math.sin((d.startAngle) - Math.PI / 4) * radius * innerFactor
)
.attr(
"x1",
d =>
Math.cos((d.startAngle) - Math.PI / 4) * radius * innerFactor
)
.attr(
"y2",
d =>
Math.sin((d.startAngle) - Math.PI / 4) * radius / outerFactor
)
.attr(
"x2",
d =>
Math.cos((d.startAngle) - Math.PI / 4) * radius / outerFactor
)
.attr("stroke", "#EEEEEE")
.attr("stroke-dasharray", `0.5, ${dashPercent}`)
.attr("stroke-width", 4)
}
然后,我需要多次调用该函数,并将externalFactor设置为安全空间的阈值。
let outerArc = 1 - 0.051
drawHyphen(svg, outerArc - 0.835, outerArc - 2.3, "1.9%")