Math d3.js如何计算距离节点中心X的每条线的新端点

Math d3.js如何计算距离节点中心X的每条线的新端点,math,d3.js,Math,D3.js,我有一个力定向图,我想把线的端点调整为距节点中心30px。我认为我需要修改tick函数来计算x1,y1和x2,y2的新坐标,但我很久没有接触几何体了,似乎无法找到正确的方程来实现这一点 任何帮助或指导都将不胜感激 更新… 所以我用下面的方法做到了这一点(感谢一位朋友)。请注意,这条线是垂直的,有一个bug。如果有人有更有效的方法,我很乐意帮忙 function distance(x1,y1,x2,y2) { y = y2 - y1; x = x2 - x1;

我有一个力定向图,我想把线的端点调整为距节点中心30px。我认为我需要修改tick函数来计算x1,y1和x2,y2的新坐标,但我很久没有接触几何体了,似乎无法找到正确的方程来实现这一点

任何帮助或指导都将不胜感激

更新…

所以我用下面的方法做到了这一点(感谢一位朋友)。请注意,这条线是垂直的,有一个bug。如果有人有更有效的方法,我很乐意帮忙

    function distance(x1,y1,x2,y2) {
      y = y2 - y1;
      x = x2 - x1;
      return Math.sqrt(x*x + y*y);
    }

    function calc_slope(d) {
      x1 = d.source.x;
      y1 = d.source.y;
      x2 = d.target.x;
      y2 = d.target.y;

      return (y2-y1)/parseFloat(x2-x1);
    }

    function calc_constant(slope, x, y) {
      return (y - (slope * x));
    }

    function calc_y(slope, constant, x){
      return (slope * x) + constant;
    }

    function adjusted_source_x(d, adjustment_size) {
      x1 = d.source.x;
      y1 = d.source.y;
      x2 = d.target.x;
      y2 = d.target.y;

      if (distance(x1,y1,x2,y2) < (2 * adjustment_size)){
        return x1;
      }

      if (x1 == x2){
        return x1;
      }

      slope = calc_slope(d);
      constant = calc_constant(slope, x1, y1);

      if (x1 < x2){
        x1_prime = x1 + adjustment_size;
        y1_prime = calc_y(slope, constant, x1_prime);

        while (distance(x1,y1,x1_prime,y1_prime) > adjustment_size){
          x1_prime = x1_prime - 1;
          y1_prime = calc_y(slope, constant, x1_prime);
        }
        return x1_prime;
      }
      else{
        x1_prime = x1 - adjustment_size;
        y1_prime = calc_y(slope, constant, x1_prime);

        while (distance(x1,y1,x1_prime,y1_prime) > adjustment_size){
          x1_prime = x1_prime + 1;
          y1_prime = calc_y(slope, constant, x1_prime);
        }
        return x1_prime; 
      }
    }

    function adjusted_source_y(d, adjustment_size) {
      x1 = d.source.x;
      y1 = d.source.y;
      x2 = d.target.x;
      y2 = d.target.y;

      if (distance(x1,y1,x2,y2) < (2 * adjustment_size)){
        return y1;
      }

      if (x1 == x2){
        if(y1 < y2){
          return (y1 + adjustment_size)
        }
        else {
          return (y1 - adjustment_size)
        }
      }

      slope = calc_slope(d);
      constant = calc_constant(slope, x1, y1);

      if (x1 < x2){
        x1_prime = x1 + adjustment_size;
        y1_prime = calc_y(slope, constant, x1_prime);

        while (distance(x1,y1,x1_prime,y1_prime) > adjustment_size){
          x1_prime = x1_prime - 1;
          y1_prime = calc_y(slope, constant, x1_prime);
        }
        return y1_prime;
      }
      else{
        x1_prime = x1 - adjustment_size;
        y1_prime = calc_y(slope, constant, x1_prime);

        while (distance(x1,y1,x1_prime,y1_prime) > adjustment_size){
          x1_prime = x1_prime + 1;
          y1_prime = calc_y(slope, constant, x1_prime);
        }
        return y1_prime; 
      }
    }

    function adjusted_target_x(d, adjustment_size) {
      x1 = d.source.x;
      y1 = d.source.y;
      x2 = d.target.x;
      y2 = d.target.y;

      if (distance(x1,y1,x2,y2) < (2 * adjustment_size)){
        return x2;
      }

      if (x1 == x2){
        return x2;
      }

      slope = calc_slope(d);
      constant = calc_constant(slope, x1, y1);

      if (x2 < x1){
        x2_prime = x2 + adjustment_size;
        y2_prime = calc_y(slope, constant, x2_prime);

        while (distance(x2,y2,x2_prime,y2_prime) > adjustment_size){
          x2_prime = x2_prime - 1;
          y2_prime = calc_y(slope, constant, x2_prime);
        }
        return x2_prime;
      }
      else{
        x2_prime = x2 - adjustment_size;
        y2_prime = calc_y(slope, constant, x2_prime);

        while (distance(x2,y2,x2_prime,y2_prime) > adjustment_size){
          x2_prime = x2_prime + 1;
          y2_prime = calc_y(slope, constant, x2_prime);
        }
        return x2_prime; 
      }
    }

    function adjusted_target_y(d, adjustment_size) {
      x1 = d.source.x;
      y1 = d.source.y;
      x2 = d.target.x;
      y2 = d.target.y;

      if (distance(x1,y1,x2,y2) < (2 * adjustment_size)){
        return y2;
      }

      if (x1 == x2){
        if(y2 < y1){
          return (y2 + adjustment_size)
        }
        else {
          return (y2 - adjustment_size)
        }
      }

      slope = calc_slope(d);
      constant = calc_constant(slope, x1, y1);

      if (x2 < x1){
        x2_prime = x2 + adjustment_size;
        y2_prime = calc_y(slope, constant, x2_prime);

        while (distance(x2,y2,x2_prime,y2_prime) > adjustment_size){
          x2_prime = x2_prime - 1;
          y2_prime = calc_y(slope, constant, x2_prime);
        }
        return y2_prime;
      }
      else{
        x2_prime = x2 - adjustment_size;
        y2_prime = calc_y(slope, constant, x2_prime);

        while (distance(x2,y2,x2_prime,y2_prime) > adjustment_size){
          x2_prime = x2_prime + 1;
          y2_prime = calc_y(slope, constant, x2_prime);
        }
        return y2_prime; 
      }
    }

    function tick() {
      node.attr("cx", function(d) { return d.x; })
        .attr("cy", function(d) { return d.y; })
        .attr("transform", function(d) { return "translate(" + d.x + "," + d.y + ")";});
      link.attr("x1", function(d) { return adjusted_source_x(d, 45); })
        .attr("y1", function(d) { return adjusted_source_y(d, 45); })
        .attr("x2", function(d) { return adjusted_target_x(d, 45); })
        .attr("y2", function(d) { return adjusted_target_y(d, 45); });
    }
功能距离(x1,y1,x2,y2){
y=y2-y1;
x=x2-x1;
返回Math.sqrt(x*x+y*y);
}
函数计算斜率(d){
x1=d.source.x;
y1=d.source.y;
x2=d.target.x;
y2=d.target.y;
返回(y2-y1)/浮动(x2-x1);
}
函数计算常数(斜率,x,y){
返回(y-(斜率*x));
}
函数计算(斜率,常数,x){
返回(斜率*x)+常数;
}
功能调整源(d,调整大小){
x1=d.source.x;
y1=d.source.y;
x2=d.target.x;
y2=d.target.y;
if(距离(x1、y1、x2、y2)<(2*调整尺寸)){
返回x1;
}
如果(x1==x2){
返回x1;
}
坡度=计算坡度(d);
常数=计算常数(斜率,x1,y1);
if(x1调整大小){
x1_素数=x1_素数-1;
y1_素数=计算y(斜率,常数,x1_素数);
}
返回x1_素数;
}
否则{
x1_素数=x1-调整_大小;
y1_素数=计算y(斜率,常数,x1_素数);
while(距离(x1,y1,x1_素数,y1_素数)>调整大小){
x1_素数=x1_素数+1;
y1_素数=计算y(斜率,常数,x1_素数);
}
返回x1_素数;
}
}
功能调整源(d,调整大小){
x1=d.source.x;
y1=d.source.y;
x2=d.target.x;
y2=d.target.y;
if(距离(x1、y1、x2、y2)<(2*调整尺寸)){
返回y1;
}
如果(x1==x2){
if(y1调整大小){
x1_素数=x1_素数-1;
y1_素数=计算y(斜率,常数,x1_素数);
}
返回y1_素数;
}
否则{
x1_素数=x1-调整_大小;
y1_素数=计算y(斜率,常数,x1_素数);
while(距离(x1,y1,x1_素数,y1_素数)>调整大小){
x1_素数=x1_素数+1;
y1_素数=计算y(斜率,常数,x1_素数);
}
返回y1_素数;
}
}
功能调整目标(d,调整大小){
x1=d.source.x;
y1=d.source.y;
x2=d.target.x;
y2=d.target.y;
if(距离(x1、y1、x2、y2)<(2*调整尺寸)){
返回x2;
}
如果(x1==x2){
返回x2;
}
坡度=计算坡度(d);
常数=计算常数(斜率,x1,y1);
if(x2调整大小){
x2_素数=x2_素数-1;
y2_素数=计算y(斜率,常数,x2_素数);
}
返回x2_素数;
}
否则{
x2_prime=x2-调整_尺寸;
y2_素数=计算y(斜率,常数,x2_素数);
while(距离(x2,y2,x2_素数,y2_素数)>调整大小){
x2_素数=x2_素数+1;
y2_素数=计算y(斜率,常数,x2_素数);
}
返回x2_素数;
}
}
功能调整目标(d,调整大小){
x1=d.source.x;
y1=d.source.y;
x2=d.target.x;
y2=d.target.y;
if(距离(x1、y1、x2、y2)<(2*调整尺寸)){
返回y2;
}
如果(x1==x2){
if(y2调整大小){
x2_素数=x2_素数-1;
y2_素数=计算y(斜率,常数,x2_素数);
}
返回y2_素数;
}
否则{
x2_prime=x2-调整_尺寸;
y2_素数=计算y(斜率,常数,x2_素数);
while(距离(x2,y2,x2_素数,y2_素数)>调整大小){
x2_素数=x2_素数+1;
y2_素数=计算y(斜率,常数,x2_素数);
}
返回y2_素数;
}
}
函数tick(){
attr(“cx”,函数(d){return d.x;})
.attr(“cy”,函数(d){返回d.y;})
.attr(“transform”,函数(d){return“translate”(“+d.x+”,“+d.y+”)”);});
attr(“x1”,函数(d){return adjusted_source_x(d,45);})
.attr(“y1”,函数(d){return adjusted_source_y(d,45);})
.attr(“x2”,函数(d){return adjusted_target_x(d,45);})
.attr(“y2”,函数(d){return adjusted_target_y(d,45);});
}

如果您知道节点的位置,则无需使用强制布局。使用
链接距离可能更简单