我想我明白你在寻找什么,所以我会尝试一下:
正如您可能从 d3.js 文档中猜到的那样,d3.arc() 没有在一端阐明观点所需的方法。两端都应用了填充和圆角,我看不出它们如何在两端形成一个点,更不用说一个了。
我想到了两种解决方案(可能有很多我什至无法想象)
- 根据其结束角度,剪掉每个圆弧的末端,并附加一个三角形或其他类似的形状(或者,应用某种遮罩将末端修剪成一个点)
- 尝试根据您的需求重新设计 d3.arc(),接受以模块化方式开发/完善 d3 的邀请。
就我个人而言,我认为选项一可能不太干净,而且可能更难设计。选项二应该是可行的,并鼓励深入研究并制作模块:
小文件固然不错,但模块化也能让 D3 变得更有趣。微型图书馆更容易理解、开发和测试。它们使新人更容易参与并做出贡献。它们减少了“核心模块”和“插件”之间的区别,并加快了 D3 功能的开发速度。 (https://github.com/d3/d3/blob/master/CHANGES.md https://github.com/d3/d3/blob/master/CHANGES.md)
我想我应该尝试一下。
我已经进行了一次尝试,这可能是基于 d3.arc() 函数的 V 形尖弧模块的开始。
d3-shape.js 模块中 d3.arc() 函数的圆角部分可能是最佳查看位置,因为它显示了对圆弧末端的修改。如果是圆角,模块中修改圆弧的部分如下所示:
context.arc(t0.cx, t0.cy, rc1, Math.atan2(t0.y01, t0.x01), Math.atan2(t0.y11, t0.x11), !cw);
context.arc(0, 0, r1, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
context.arc(t1.cx, t1.cy, rc1, Math.atan2(t1.y11, t1.x11), Math.atan2(t1.y01, t1.x01), !cw);
首先处理外边缘(如上所示)。第一行是后外角的倒圆,第三行是前外角的倒圆。只需删除第三条线即可形成尖弧(如果您也将其从内边缘删除)。然后剩下的挑战是使弧的另一端变平,我通过使用起始角度和内半径和外半径来找到弧的角以创建平端来完成此操作。
最终结果是这样的:
// get tail coordinate (outer)
var tailOuter = {};
tailOuter.x = Math.cos(a0) * r1; // a0 = starting angle
tailOuter.y = Math.sin(a0) * r1; // r1 = outer radius
context.moveTo(tailOuter.x, tailOuter.y);
context.arc(0, 0, r1, Math.atan2(t0.cy + t0.y11, t0.cx + t0.x11), Math.atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw);
我已经整理了一个快速而肮脏的module http://bl.ocks.org/andrew-reid/3375e602cc6c00c4e3ea4799d171ee27它采用 d3.arc() 函数并创建 d3.cheveronArc() 函数。它是对 d3.arc() 的彻底修改,只有四个方法(inner/outerRadius()
,start/endAngle()
)。它无法检查可能导致不当行为的参数(例如:V 形比弧长)。这只是一个概念证明,尽管我对它看起来相当快速的尝试感到满意:
正如您可能注意到的,最内圈的尾部附近有一个奇怪的形状,小的内半径似乎会导致类似的问题。
代码可以在以下网址查看:http://bl.ocks.org/andrew-reid/3375e602cc6c00c4e3ea4799d171ee27 http://bl.ocks.org/andrew-reid/3375e602cc6c00c4e3ea4799d171ee27
看着它,我觉得我想添加一个选项,将 V 形的反面添加到弧线的后端,以获得更好的视觉效果,但这是另一个问题。