标签外圆弧(饼图)d3.js
我是 d3.js 的新手,我正在尝试用它制作饼图。 我只有一个问题:我无法将标签放在弧线之外...... 标签使用 arc.centroid 定位
arcs.append("svg:text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle")
谁可以帮我解决这个问题?
I'm new to d3.js and I"m trying to make a Pie-chart with it.
I have only one problem: I can't get my labels outside my arcs...
The labels are positioned with arc.centroid
arcs.append("svg:text")
.attr("transform", function(d) {
return "translate(" + arc.centroid(d) + ")";
})
.attr("text-anchor", "middle")
Who can help me with this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(8)
这是我满意的低成本答案。它将所有标签水平推出(这就是我有额外空间的地方):
This was the low-cost answer I was happy with. It pushes all the labels out horizontally (that's where I had the extra space):
下面的 CoffeeScript 让我的标签仍然位于饼图切片内,但朝向外边缘:
The following CoffeeScript worked for me to get labels still inside the pie slices, but toward the outer edge:
我通过在饼图外部绘制百分比作为标签来实现相同的效果,这里是代码 http://bl.ocks.org/farazshuja/e2cb52828c080ba85da5458e2304a61f
I achieved the same by drawing percentage as labels outside the pie chart graph, here is the code http://bl.ocks.org/farazshuja/e2cb52828c080ba85da5458e2304a61f
是的,宝贝,这是SOHCAHTOA
yes baby, it's SOHCAHTOA
我不知道这是否有帮助,但我能够创建弧形,将文本放置在弧形上和弧形外部。在一种情况下,我将弧的大小放置在弧内,我旋转弧上的文本以匹配弧的角度。在另一种情况下,我将文本放置在弧线之外,它只是水平的。代码位于:http://bl.ocks.org/2295263
我最好的,
弗兰克
I don't know if this helps but I was able to create arcs where I place text, both, on the arc and just outside it. In one case, where I place magnitudes of the arc within the arcs, I rotate the text on the arc to match the angle of the arc. In the other, where I place the text outside of the arc, it is simply horizontal. The code is located at: http://bl.ocks.org/2295263
My Best,
Frank
特别是对于饼图,
d3.layout.pie()
函数将使用startAngle
和endAngle
属性格式化数据。半径可以是您想要的任何值(您希望将标签放置在离中心多远的地方)。将这些信息与几个三角函数相结合,您可以确定标签的 x 和 y 坐标。
考虑这个要点/块。
关于文本的 x/y 定位,神奇之处在于这一行(为了便于阅读而格式化):
((d.endAngle - d.startAngle) / 2) + d.startAngle
为我们提供了角度(theta) 以弧度表示。(radius - 12)
是我为文本位置选择的任意半径。-1 *
y 轴反转(见下文)。使用的三角函数是:cos = 邻接/斜边 和sin = 相反/斜边。但为了让这些与我们的标签兼容,我们需要考虑一些事情。
这让事情变得相当混乱,基本上具有交换 sin 和 cos 的效果。我们的三角函数就变成:
sin = 邻接/斜边
和cos = 相反/斜边
。我们用
sin(radians) = x / r
和cos(radians) = y / r
替换变量名称。经过一些代数运算,我们可以分别得到 x 和 y 的函数r * sin(radians) = x
和r * cos(radians) = y
。从那里,只需将它们插入到转换/翻译属性中即可。这会将标签放在正确的位置,为了使它们看起来很漂亮,您需要一些如下的样式逻辑:
这将使标签从 10:30 点到 1:30 点以及从 4:30 点'时钟到 7:30 点的锚点位于中间(它们位于上方和下方),标签从 1:30 点到 4:30 点的锚点位于左侧(它们位于右侧),以及标签从 7:30 点到 10:30 点锚点在右侧(它们在左侧)。
相同的公式可用于任何 D3 径向图,唯一的区别在于如何确定角度。
我希望这可以帮助任何遇到它的人!
Specifically for pie charts, the
d3.layout.pie()
function will format data with astartAngle
andendAngle
attributes. The radius can be whatever you desire (how far out from the center you would like to place the label).Combining these pieces of information with a couple trigonometric functions lets you determine the x and y coordinates for labels.
Consider this gist/block.
Regarding the x/y positioning of the text, the magic is in this line (formatted for readability):
((d.endAngle - d.startAngle) / 2) + d.startAngle
gives us our angle (theta) in radians.(radius - 12)
is the arbitrary radius I chose for the position of the text.-1 *
the y axis is inverted (see below).The trig functions used are:
cos = adjacent / hypotenuse
andsin = opposite / hypotenuse
. But there are a couple things we need to consider to make these work with our labels.That messes things up quite a bit and basically has the effect of swapping
sin
andcos
. Our trig functions then become:sin = adjacent / hypotenuse
andcos = opposite / hypotenuse
.Substituting variable names we have
sin(radians) = x / r
andcos(radians) = y / r
. After some algebraic manipulation we can get both functions in terms of x and y respectivelyr * sin(radians) = x
andr * cos(radians) = y
. From there, just plug those into the transform/translate attribute.That'll put the labels in the right location, to make them look fancy, you need some styling logic like this:
This will make the labels from 10:30 o'clock to 1:30 o'clock and from 4:30 o'clock to 7:30 o'clock anchor in the middle (they are above and below), the labels from 1:30 o'clock to 4:30 o'clock anchor on the left (they are to the right), and the labels from 7:30 o'clock to 10:30 o'clock anchor on the right (they are to the left).
The same formulas can be used for any D3 radial graph, the only difference is how you determine the angle.
I hope this helps anyone stumbling across it!
谢谢!
我找到了一种不同的方法来解决这个问题,但你的似乎更好:-)
我创建了第二个半径更大的圆弧,并用它来定位我的标签。
Thanks!
I found a different way to solve this problem, but yours seems better :-)
I created a second arc with a bigger radius and used it to position my labels.
我可以用三角学来解决这个问题:)。
请参阅小提琴: http://jsfiddle.net/nrabinowitz/GQDUS/
基本上,调用
arc .centroid(d)
返回一个[x,y]
数组。您可以使用毕达哥拉斯定理来计算斜边,即从饼图中心到圆弧质心的线的长度。然后,您可以使用计算x/h *desiredLabelRadius
和y/h *desiredLabelRadius
来计算标签锚点所需的x,y
:这里唯一的缺点是
text-anchor: middle
不再是一个很好的选择 - 你最好根据文本的哪一侧设置text-anchor
我们正在做的馅饼:I can solve that problem - with trigonometry :).
See fiddle: http://jsfiddle.net/nrabinowitz/GQDUS/
Basically, calling
arc.centroid(d)
returns an[x,y]
array. You can use the Pythagorean Theorem to calculate the hypotenuse, which is the length of the line from the center of the pie to the arc centroid. Then you can use the calculationsx/h * desiredLabelRadius
andy/h * desiredLabelRadius
to calculate the desiredx,y
for your label anchor:The only downside here is that
text-anchor: middle
isn't a great choice anymore - you'd be better off setting thetext-anchor
based on which side of the pie we're on: