我想我明白你在找什么,所以我会试一试:
正如您可能从 d3.js 文档中猜到的那样,d3.arc() 没有在一端提出观点所需的方法。两端都应用了填充和圆角,我看不出它们如何在两端形成一个点,更不用说一个了。
想到了两个解决方案(可能有很多我什至无法想象)
- 根据弧的结束角度,剪掉每条弧的末端,并附加一个三角形或其他类似的形状(或者,应用某种蒙版将末端修剪成一个点)
- 尝试根据您的需要重新设计 d3.arc(),接受以模块化方式开发/改进 d3 的邀请。
就个人而言,我认为选项一可能不太干净,而且可能更难设计。选项二应该是可行的,并且在这种鼓励下潜入并制作模块:
小文件很好,但模块化也是为了让 D3 更有趣。微型图书馆更容易理解、开发和测试。它们使新人更容易参与和贡献。它们减少了“核心模块”和“插件”之间的区别,并加快了 D3 功能的开发速度。(https://github.com/d3/d3/blob/master/CHANGES.md)
我想我会试一试。
我已经进行了一次尝试,这可能是基于 d3.arc() 函数的雪佛龙尖弧模块的开始。
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);
我已经组装了一个快速而肮脏的模块,它采用 d3.arc() 函数并创建一个 d3.cheveronArc() 函数。这是对 d3.arc() 的彻底修改,只有四个方法(inner/outerRadius()
, start/endAngle()
)。它无法检查可能导致不当行为的参数(例如:V 形比弧长)。这只是一个概念证明,尽管我很高兴它看起来是一个相当快速的尝试:
您可能会注意到,最内圈的尾部附近有一个奇怪的形状,小内半径似乎会导致一些类似的问题。
代码可见:http:
//bl.ocks.org/andrew-reid/3375e602cc6c00c4e3ea4799d171ee27
看着它,我觉得我想添加将人字形的倒数添加到弧的后端以获得更好的视觉效果的选项,但这是一个不同的问题。