我试图d3.arc
在另一个弧内完美地嵌套生成的弧.
我可以通过"自己动手"来做到这一点:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
function arc_position(x, y, radius, angle) {
return {
x: x + (radius * Math.cos(angle)),
y: y + (radius * Math.sin(angle))
};
}
function describe_arc(x, y, radius, startAngle, endAngle) {
var s = arc_position(x, y, radius, endAngle);
var e = arc_position(x, y, radius, startAngle);
var sweep = e - s <= 180 ? '0' : '1';
var d = [
'M', s.x, s.y,
'A', radius, radius, 0, sweep, 0, e.x, e.y
].join(' ');
return d;
}
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500)
.append("g");
var s = arc_position(250, 250, 200, Math.PI/2);
var e = arc_position(250, 250, 200, (Math.PI * 3)/2);
svg.append("path")
.style("fill", "none")
.style("stroke", "orange")
.style("stroke-width", "20px")
.attr("d", describe_arc(250,250,180,(Math.PI * 3)/2, Math.PI/2));
svg.append("path")
.style("fill", "none")
.style("stroke", "orange")
.style("stroke-width", "20px")
.attr("d", "M" + (s.x + 30) + "," + s.y + "L" + (e.x + 30) + "," + e.y);
svg.append("path")
.style("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", "20px")
.attr("d", describe_arc(250,250,200,(Math.PI * 3)/2, Math.PI/2));
svg.append("path")
.style("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", "20px")
.attr("d", "M" + (s.x + 10) + "," + s.y + "L" + (e.x + 10) + "," + e.y);
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
但我无法弄清楚使用的方法d3.arc
:
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500)
.append("g")
.attr("transform","translate(250,250)");
var arc = d3.arc()
.innerRadius(0)
.outerRadius(200)
.startAngle(0)
.endAngle(Math.PI);
svg.append("path")
.style("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", "20px")
.attr("d", arc());
arc.outerRadius(200 - 40);
svg.append("path")
.style("fill", "none")
.style("stroke", "orange")
.style("stroke-width", "20px")
.attr("d", arc())
.attr("transform", "translate(20,0)")
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)
有任何想法吗?
我不认为有一个很好的方法来做这个只是使用d3.arc
因为这是用于绘制圆的部分,你试图绘制一个部分椭圆.
您可以使用笔划宽度和内弧的半径生成角度偏移offsetAngle = sin(stroke width / inner radius)
.弧startAngle
是offsetAngle
和,endAngle
是Math.PI - offsetAngle
.
不幸的是,这将产生包括圆的中心点的路径.你可以通过L0,0
从生成的路径(innerArc().replace("L0,0","")
)中删除一些有效的东西,这将给你你想要的东西,虽然是一种丑陋的方式.
因为它是一个相当简单的路径,所以最好使用自己的路径生成器来代替它.
<!DOCTYPE html>
<html>
<head>
<script data-require="d3@4.0.0" data-semver="4.0.0" src="https://d3js.org/d3.v4.min.js"></script>
</head>
<body>
<script>
var svg = d3.select("body")
.append("svg")
.attr("width", 500)
.attr("height", 500)
.append("g")
.attr("transform","translate(250,250)");
var outerRadius = 200;
var stroke = 20;
var innerRadius = outerRadius - stroke;
var innerAngle = Math.sin(stroke/innerRadius);
var outerArc = d3.arc()
.innerRadius(0)
.outerRadius(outerRadius)
.startAngle(0)
.endAngle(Math.PI);
var innerArc = d3.arc()
.innerRadius(0)
.outerRadius(innerRadius)
.startAngle(innerAngle)
.endAngle(Math.PI - innerAngle);
svg.append("path")
.style("fill", "none")
.style("stroke", "steelblue")
.style("stroke-width", stroke)
.attr("d", outerArc());
svg.append("path")
.style("fill", "none")
.style("stroke", "orange")
.style("stroke-width", stroke)
.attr("d", innerArc().replace("L0,0",""));
</script>
</body>
</html>
Run Code Online (Sandbox Code Playgroud)