如何将svg形状放在一个圆圈中?

时间:2012-12-02 19:25:25

标签: d3.js

我正在玩D3.js,我得到了大部分工作。但是我想把我的svg形状放在一个圆圈里。所以我将用颜色和文字显示数据的差异。我知道如何绘制圆圈和饼图,但我想基本上有一个相同大小的圆圈。并没有让它们重叠,顺序无关紧要。我不知道从哪里开始,找出x& y为每个圆圈。

2 个答案:

答案 0 :(得分:9)

如果我理解正确,这是一个相当标准的数学问题:

只需以适当的步长循环一些 angle 变量,然后使用sin()cos()来计算x和y值。

例如:

假设您正在尝试放置3个对象。圆圈有360度。所以每个物体与下一个物体相距120度。如果您的对象大小为20x20像素,请将它们放在以下位置:

 x1 = sin(  0 * pi()/180) * r + xc - 10;  y1 = cos(  0 * pi()/180) * r + yc - 10
 x2 = sin(120 * pi()/180) * r + xc - 10;  y2 = cos(120 * pi()/180) * r + yc - 10
 x3 = sin(240 * pi()/180) * r + xc - 10;  y3 = cos(240 * pi()/180) * r + yc - 10

此处,r是圆的半径,(xc, yc)是圆的中心点的坐标。 -10's确保对象的圆心(而不是左上角)。 * pi()/180将度数转换为弧度,这是sin()cos()所需的大多数实现的单位。

注意:这会将形状均匀分布在圆周围。为了确保它们不重叠,您必须选择足够大的r。如果物体具有简单且相同的边界,则只需布置其中的10个并找出所需的半径,然后,如果需要放置20,则将半径设为两倍,将三倍设为大等等。如果物体形状不规则,并且您希望将它们放在圆圈周围的最佳顺序中以找到可能的最小圆圈,则此问题将变得非常混乱。也许这里有一个库,但我没有一个在我的头脑中,因为我没有使用过D3.js,我不确定它是否会为你提供这个功能。

答案 1 :(得分:6)

对于任意大小的形状,使用D3的tree布局,这是另一种方法:http://jsfiddle.net/nrabinowitz/5CfGG/

tree布局(docsexample)会根据给定的半径和返回两者之间分隔的函数计算出每个项目的x,y位置。任何两个项目的中心。在这个例子中,我使用了不同大小的圆圈,因此它们之间的分离是它们半径的函数:

var tree = d3.layout.tree()
    .size([360, radius])
    .separation(function(a, b) {
        return radiusScale(a.size) + radiusScale(b.size);
    });

使用D3 tree布局解决了第一个问题,将项目放在一个圆圈中。正如@Markus指出的那样,第二个问题是如何计算圆的正确半径。为了方便起见,我在这里采取了一种稍微粗略的方法:我估计圆的周长是各种项目的直径之和,其间有给定的填充,然后从圆周计算半径:

var roughCircumference = d3.sum(data.map(radiusScale)) * 2 +
        padding * (data.length - 1),
    radius = roughCircumference / (Math.PI * 2);

这里的圆周不准确,而且圆圈中的项目越少,这个就越少越准确,但它足够接近这个目的。