如何使用linkRadial在两点之间绘制链接? [英] How to use linkRadial to draw a link between two points?

查看:29
本文介绍了如何使用linkRadial在两点之间绘制链接?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要手动在圆上的点与聚集在所述圆的中心的点之间绘制一些链接.我有用于源点和目标点的x,y对,但是我不希望它们之间有一条简单的直线.我想要一条曲线(类似于在树状图中找到的链接).我可以使用 linkHorizo​​ntal linkVertical ,但是它们的切线是恒定的.我想使用 linkRadial 并将切线设为该特定弧点处的径向线(我也具有该角度).

I need to manually draw some links between points on a circle and points clustered in the centre of said circle. I have the x,y pairs for the source and target points, but I don't want a simple straight line between them; I want a curved line (similar to the links that are found in tree diagrams). I could use linkHorizontal or linkVertical but their tangents are constant; I want to use linkRadial and have the tangent be the radial line at that particular arc point (the degree of which I also have).

我不理解 linkRadial API;它需要一个角度和一个半径,而不是x或y点.如何将我的两个x,y对(以及径向线角度)转换为期望的角度和半径?

I don't understand the linkRadial API though; it wants an angle and a radius, not an x or y point. How do I convert my two x,y pairs (and the radial line angle) into the angle and radius this is expecting?

推荐答案

由于您的数据数组的位置为 x y (源点和目标点的x,y对" ),则必须将它们转换为 angle radius .让我们看看如何做到这一点.

Since you have a data array with the x and y positions ("I have the x,y pairs for the source and target points"), you'll have to convert them to angle and radius. Let's see how to do it.

首先,让我们看一个具有固定坐标的示例.例如,假设您具有此数据数组,其位置为 x y :

Firstly, let's see an example with fixed coordinates. For instance, suppose you have this data array, with the x and y positions:

var data = [{
    source: {y: 150,x: 75
    },
    target: {y: 300,x: 0
    }
}, {
    source: {y: 150,x: 75
    },
    target: {y: 0,x: 0
    }
}, {
    source: {y: 150,x: 75
    },
    target: {y: 150,x: 150
    }
}, ];

使用此链接生成器...

Using this link generator...

var link = d3.linkHorizontal()
    .x(function(d) {
        return d.y;
    })
    .y(function(d) {
        return d.x;
    });

...您将得到一个这样的图表:

... you'll have a chart like this:

var data = [{
  source: {
    y: 150,
    x: 75
  },
  target: {
    y: 300,
    x: 0
  }
}, {
  source: {
    y: 150,
    x: 75
  },
  target: {
    y: 0,
    x: 0
  }
}, {
  source: {
    y: 150,
    x: 75
  },
  target: {
    y: 150,
    x: 150
  }
}, ];

var svg = d3.select("svg");

var link = d3.linkHorizontal()
  .x(function(d) {
    return d.y;
  })
  .y(function(d) {
    return d.x;
  });

svg.selectAll(null)
  .data(data)
  .enter()
  .append("path")
  .attr("fill", "none")
  .attr("stroke", "blue")
  .attr("d", link);

<script src="https://d3js.org/d3.v4.js"></script>
<svg></svg>

我们如何将其转换为可以与 d3.linkRadial()一起使用的数据集?

How can we convert this to a data set that can be used with d3.linkRadial()?

一个选项是对每个对象进行迭代,使用基本的三角函数填充 angle radius 属性:

One option is iterating with each object, using basic trigonometry to populate the angle and radius properties:

var radialData = data.map(function(d) {
    return {
        source: {
            x: 0,
            y: 0
        },
        target: {
            x: Math.atan2(d.target.y - d.source.y, d.target.x - d.source.x) - Math.PI,
            y: Math.sqrt((d.target.x - d.source.x) * (d.target.x - d.source.x) + (d.target.y - d.source.y) * (d.target.y - d.source.y))
        }
    };
});

然后,使用此链接生成器:

Then, using this link generator:

var linkRadial = d3.linkRadial()
    .angle(function(d) {
        console.log(d)
        return d.x;
    })
    .radius(function(d) {
        return d.y;
    });

我们将拥有这个:

var data = [{
  source: {
    y: 150,
    x: 75
  },
  target: {
    y: 300,
    x: 0
  }
}, {
  source: {
    y: 150,
    x: 75
  },
  target: {
    y: 0,
    x: 0
  }
}, {
  source: {
    y: 150,
    x: 75
  },
  target: {
    y: 150,
    x: 150
  }
}, ];

var svg = d3.select("svg");

var radialData = data.map(function(d) {
  return {
    source: {
      x: 0,
      y: 0
    },
    target: {
      x: Math.atan2(d.target.y - d.source.y, d.target.x - d.source.x) - Math.PI,
      y: Math.sqrt((d.target.x - d.source.x) * (d.target.x - d.source.x) + (d.target.y - d.source.y) * (d.target.y - d.source.y))
    }
  };
});

var g = svg.append("g")
  .attr("transform", "translate(150,75)")

var linkRadial = d3.linkRadial()
  .angle(function(d) {
    return d.x;
  })
  .radius(function(d) {
    return d.y;
  });

g.selectAll(null)
  .data(radialData)
  .enter()
  .append("path")
  .attr("fill", "none")
  .attr("stroke", "red")
  .attr("d", linkRadial);

<script src="https://d3js.org/d3.v4.js"></script>
<svg></svg>

现在将两个生成器放在一起,以进行比较:

Now both generators together, for comparison:

var data = [{
  source: {
    y: 150,
    x: 75
  },
  target: {
    y: 300,
    x: 0
  }
}, {
  source: {
    y: 150,
    x: 75
  },
  target: {
    y: 0,
    x: 0
  }
}, {
  source: {
    y: 150,
    x: 75
  },
  target: {
    y: 150,
    x: 150
  }
}, ];

var svg = d3.select("svg");

var link = d3.linkHorizontal()
  .x(function(d) {
    return d.y;
  })
  .y(function(d) {
    return d.x;
  });

svg.selectAll(null)
  .data(data)
  .enter()
  .append("path")
  .attr("fill", "none")
  .attr("stroke", "blue")
  .attr("d", link);

var radialData = data.map(function(d) {
  return {
    source: {
      x: 0,
      y: 0
    },
    target: {
      x: Math.atan2(d.target.y - d.source.y, d.target.x - d.source.x) - Math.PI,
      y: Math.sqrt((d.target.x - d.source.x) * (d.target.x - d.source.x) + (d.target.y - d.source.y) * (d.target.y - d.source.y))
    }
  };
});

var g = svg.append("g")
  .attr("transform", "translate(150,75)")

var linkRadial = d3.linkRadial()
  .angle(function(d) {
    return d.x;
  })
  .radius(function(d) {
    return d.y;
  });

g.selectAll(null)
  .data(radialData)
  .enter()
  .append("path")
  .attr("fill", "none")
  .attr("stroke", "red")
  .attr("d", linkRadial);

<script src="https://d3js.org/d3.v4.js"></script>
<svg></svg>

这篇关于如何使用linkRadial在两点之间绘制链接?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆