我和D3.js玩了一下,我得到了大部分工作.但是我想把我的svg形状放在一个圆圈里.所以我将用颜色和文字显示数据的差异.我知道如何绘制圆圈和饼图,但我想基本上有一个相同大小的圆圈.并没有让它们重叠,顺序无关紧要.我不知道从哪里开始,找出每个圆圈的x和y.
如果我理解正确,这是一个相当标准的数学问题:
只需以适当的步长循环一些角度变量,然后使用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
Run Code Online (Sandbox Code Playgroud)
这里r是圆的半径,是(xc, yc)圆的中心点的坐标.在-10's确保对象有他们的圆心(而不是他们的左上角).的* pi()/180程度转换为弧度,这是单位大多数实现sin()和cos()要求.
注意:这会将形状均匀分布在圆周围.为了确保它们不重叠,你必须选择r足够大的.如果物体具有简单且相同的边界,则只需布置其中的10个并找出所需的半径,然后,如果需要放置20,则将半径设为两倍,将三倍设为大等等.如果物体形状不规则,并且您希望将它们放在圆圈周围的最佳顺序中以找到可能的最小圆圈,则此问题将变得非常混乱.也许这里有一个库,但我没有一个在我的头脑中,因为我没有使用过D3.js,我不确定它是否会为你提供这个功能.
对于任意大小的形状,使用D3的tree布局,这是另一种方法:http://jsfiddle.net/nrabinowitz/5CfGG/
该tree布局(文档,例如)将计算出X,你每个项目的Ÿ位置,根据给定的半径和返回任何两个项目的中心之间的距离的函数.在这个例子中,我使用了不同大小的圆,因此它们之间的分离是它们的半径的函数:
var tree = d3.layout.tree()
.size([360, radius])
.separation(function(a, b) {
return radiusScale(a.size) + radiusScale(b.size);
});
Run Code Online (Sandbox Code Playgroud)
使用D3 tree布局解决了第一个问题,将项目布置成圆形.正如@Markus所说,第二个问题是如何计算圆的正确半径.我已经采取了略显粗糙的方式在这里,对权宜之计:我估计圆作为各种物品的直径总和的圆周,具有给定的填充之间,然后从圆周半径计算:
var roughCircumference = d3.sum(data.map(radiusScale)) * 2 +
padding * (data.length - 1),
radius = roughCircumference / (Math.PI * 2);
Run Code Online (Sandbox Code Playgroud)
这里的圆周不准确,而且圆圈中的项目越少,这个就越少越准确,但它足够接近这个目的.