Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/438.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在d3中不同尺寸的矩形之间绘制有向箭头?_Javascript_D3.js_Svg - Fatal编程技术网

Javascript 如何在d3中不同尺寸的矩形之间绘制有向箭头?

Javascript 如何在d3中不同尺寸的矩形之间绘制有向箭头?,javascript,d3.js,svg,Javascript,D3.js,Svg,我想在矩形(由矩形表示的节点)之间绘制有向圆弧,这样箭头尖总是以优雅的方式击中边缘。我看过很多关于如何对圆(由圆表示的节点)执行此操作的SO帖子。非常有趣的是,大多数d3示例都涉及圆和正方形(尽管正方形的程度较低) 我有一个示例代码。现在我最好的尝试只能从一个中心点画到另一个中心点。我可以移动端点(箭头应该在哪里),但在尝试拖动矩形时,圆弧的行为与预期不符 这是我得到的。 但我需要这样的东西。 关于如何在d3中轻松做到这一点,有什么想法吗?是否有一些内置的库/函数可以帮助处理这类事情(比如拖

我想在矩形(由矩形表示的节点)之间绘制有向圆弧,这样箭头尖总是以优雅的方式击中边缘。我看过很多关于如何对圆(由圆表示的节点)执行此操作的SO帖子。非常有趣的是,大多数
d3
示例都涉及圆和正方形(尽管正方形的程度较低)

我有一个示例代码。现在我最好的尝试只能从一个中心点画到另一个中心点。我可以移动端点(箭头应该在哪里),但在尝试拖动矩形时,圆弧的行为与预期不符

这是我得到的。

但我需要这样的东西。


关于如何在
d3
中轻松做到这一点,有什么想法吗?是否有一些内置的库/函数可以帮助处理这类事情(比如拖动功能)

解决问题的一个简单算法是

  • 拖动节点时,对其每个传入/传出边执行以下操作
    • a
      拖动节点,让
      b
      通过传出/传入边缘到达节点
    • lineSegment
      成为
      a
      b
    • 计算
      a
      lineSegment
      的交点,方法是迭代构成方框的4个线段,并检查它们与
      lineSegment
      的交点,让
      ia
      成为
      a
      lineSegment
      其中一个线段的交点,以类似的方式查找
      ib
我考虑过但尚未解决的角落案例

  • 当一个长方体的中心位于另一个长方体内部时,不会有两个线段交点
  • 当两个交点相同时!(在编辑中解决了此问题)
  • 当图形是一个图形时,边将彼此重叠渲染

编辑:添加了检查
ia===ib
以避免从左上角创建边,您可以在plunkr演示中看到这一点

$(文档).ready(函数(){
变量图={
节点:[
{id:'n1',x:10,y:10,宽:200,高:200},
{id:'n2',x:10,y:270,宽:200,高:250},
{id:'n3',x:400,y:270,宽:200,高:300}
],
边缘:[
{开始:'n1',停止:'n2'},
{开始:'n2',停止:'n3'}
],
节点:函数(id){
如果(!this.nmap){
this.nmap={};
对于(var i=0;i
对于源箭头,我只是用白色填充矩形来绘制箭头

对于目标,它比你想象的要复杂一点。你必须计算源矩形和目标矩形的位置,并相应地画出你的箭头

我已经做了一个tarmid函数,除了你的mid函数。你的mid函数计算箭头源点,这很好。但是对于目标点,我使用了tarmid函数,它是:

tarmid: function(d) {

            var startnode = this.node(d.start);
            var endnode = this.node(d.stop);
            if(startnode.x == endnode.x && startnode.y <= endnode.y){
              var x = endnode.width / 2.0 + endnode.x,
                y = endnode.y -17;
            }else if(startnode.x < endnode.x && startnode.y <= endnode.y){
              var x = endnode.x-17,
                y = endnode.y + startnode.height / 2.0;
            }
            return { x: x, y: y };
          }
tarmid:函数(d){
var startnode=this.node(d.start);
var endnode=this.node(d.stop);

如果(startnode.x==endnode.x&&startnode.y)如果您正在进行向下投票,请至少评论一下原因。这个解决方案让我几乎达到了目的。但是,在接受这个答案之前,我将等待一段时间,因为我正在修改示例,并注意到一些奇怪的闪烁(从左上角画出的圆弧和闪烁).正如我在回答中所说的,有一些拐角情况,其中涉及从顶部let拐角绘制的圆弧是因为交点是相同的,即,
ia==ib