我正在研究具有两个圆的d3视觉效果,其中较小的圆放置在较大圆的半径的边缘上。其中的codepen位于https://codepen.io/ajblack/pen/KqKpde。我有一个200像素的方形SVG,我将这些圆放入其中,然后我有两个值,uAssets和uAssetsCom,它们决定了圆圈的大小。我使用以下代码创建一个比率以确保较大的圆圈适合200像素的正方形:
var ratioToFit = (200/uAssets)/2;
然后我使用余弦来计算大圆的外半径和SVG容器的外边界之间的45度角的距离:
var key = 100*((1-Math.cos(45*Math.PI/180))/Math.cos(45*Math.PI/180))
要放置较小的圆圈,我会将cx
和cy
属性计算为内圆的半径加上此键'。
d3.select("#uAssetComCircle")
.attr("cx", function(d){return (d.radius+key);})
.attr("cy", function(d){return (d.radius+key);})
这使得内圆靠近较大圆的半径,但它关闭了大约2个像素。我可以用cx
和cy
添加硬编码的2像素来抵消这一点,但我觉得我不应该这样做。
我的数学算了吗?
答案 0 :(得分:1)
不确定我是否完全遵循您的计算,但这是一个快速重构,介绍了一些内容:
<!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>
<link rel="stylesheet" href="style.css" />
<script src="script.js"></script>
</head>
<body>
<script>
var uAssets = 17;
var uAssetsCom = 3;
var svgContainer = d3.select("body").append("svg")
.attr("width", 200)
.attr("height", 200)
.attr('id', 'circleContainer')
.append("g")
.attr("transform", "translate(" + 100 + "," + 100 + ")")
var scale = d3.scaleLinear()
.domain([0,uAssets])
.range([0,100]);
var jsonCircles = [{
"radius": uAssets,
"color": "green",
"id": "uAssetCircle"
}, {
"radius": uAssetsCom,
"color": "purple",
"id": "uAssetComCircle"
}];
var circles = svgContainer.selectAll("circle")
.data(jsonCircles)
.enter()
.append("circle");
var circleAttributes = circles
.attr("r", function(d) {
return scale(d.radius);
})
.attr("id", function(d) {
return d.id
})
.style("fill", function(d) {
return d.color;
});
d3.select("#uAssetComCircle")
.attr("cx", function(d) {
return scale(uAssets) * Math.cos(45 * (Math.PI / 180));
})
.attr("cy", function(d) {
return scale(uAssets) * Math.sin(45 * (Math.PI / 180));
})
</script>
</body>
</html>
&#13;
答案 1 :(得分:1)
我的解决方案发布在这里 https://codepen.io/ajblack/pen/qjOqmQ。 此实现使用缩放和变换的建议。我遇到的问题是对毕达哥拉斯定理的误用。我的大圆的半径是100px,我可以用它作为直角三角形的斜边。我知道我希望我的小圆圈以45度角偏移,所以我知道三角形的另外两边将是相同的长度。使用公式a²+b²=c²其中a和b是相同的值,c等于100px减去我的小圆的半径,我可以很容易地求解a和b。
a