D3小圆位于较大圆半径的边缘

时间:2017-06-02 17:06:59

标签: javascript d3.js svg

我正在研究具有两个圆的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))

要放置较小的圆圈,我会将cxcy属性计算为内圆的半径加上此键'。

d3.select("#uAssetComCircle")
  .attr("cx", function(d){return (d.radius+key);})
  .attr("cy", function(d){return (d.radius+key);})

这使得内圆靠近较大圆的半径,但它关闭了大约2个像素。我可以用cxcy添加硬编码的2像素来抵消这一点,但我觉得我不应该这样做。

我的数学算了吗?

2 个答案:

答案 0 :(得分:1)

不确定我是否完全遵循您的计算,但这是一个快速重构,介绍了一些内容:

  1. 从SVG中心点开始绘制所有绘图的翻译
  2. 用于处理从用户坐标到像素坐标的计算的d3比例。
  3. 
    
    <!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;
    &#13;
    &#13;

答案 1 :(得分:1)

我的解决方案发布在这里 https://codepen.io/ajblack/pen/qjOqmQ。 此实现使用缩放和变换的建议。我遇到的问题是对毕达哥拉斯定理的误用。我的大圆的半径是100px,我可以用它作为直角三角形的斜边。我知道我希望我的小圆圈以45度角偏移,所以我知道三角形的另外两边将是相同的长度。使用公式a²+b²=c²其中a和b是相同的值,c等于100px减去我的小圆的半径,我可以很容易地求解a和b。

a

成品看起来像small circle set inside large circle radius