好的,不要笑。我正在尝试制作弯曲的边缘,绕过源和目标之间的节点。我无法弄清楚该怎么做(我读http://js.cytoscape.org/#style/bezier-edges,但不理解它),所以我把假节点放在从源到目标的路上空的地方,并制作了一系列边缘。结果非常荒谬:
这样做的正确方法是什么?我的目标是稍微优雅一点,比如:
来自 的http://twitter.github.io/labella.js/
根据@maxkfranz的建议,我确实更接近了:
但最终决定放弃。这花了太长时间。回到直边。如果有人读过这篇文章并且可以描述一种在Cytoscape.js或其他工具中实现我的目标的方法,我很乐意听到它。为了清楚我在放弃之前所做的事情,我:
这是我的代码中最相关的部分:
function waypoints(from, to) {
let stubPoint = { row: from.data().row, col: from.data().col,
distance: 0, weight: .5, };
if (from.data().layer === to.data().layer)
return [stubPoint];
let fromCol = from.data().col,
curCol = fromCol,
toCol = to.data().col,
fromRow = from.data().row,
curRow = fromRow,
toRow = to.data().row,
fromX = from.position().x,
fromY = from.position().y,
toX = to.position().x,
toY = to.position().y,
x = d3.scaleLinear().domain([fromCol,toCol]).range([fromX,toX]),
y = d3.scaleLinear().domain([fromRow,toRow]).range([fromY,toY]);
let rowsBetween = _.range(fromRow, toRow).slice(1);
let edgeLength = pointToPointDist(x(fromCol),y(fromRow),x(toCol),y(toRow));
let points = rowsBetween.map(
(nextRow,i) => {
let colsRemaining = toCol - curCol;
let colsNow = Math.ceil(colsRemaining / Math.abs(toRow - curRow));
let nextCol = findEmptyGridCol(nextRow, curCol, curCol + colsNow);
let curX = x(curCol), curY = y(curRow),
nextX = x(nextCol), nextY = y(nextRow);
let [distanceFromEdge, distanceOnEdge] =
perpendicular_coords(curX, curY, toX, toY, nextX, nextY);
let point = {curCol, curRow,
toCol, toRow,
nextCol, nextRow,
curX, curY, toX, toY, nextX, nextY,
edgeLength,
colsNow,
//wayCol, wayRow,
distance:-distanceFromEdge * 2,
weight:distanceOnEdge / edgeLength,
};
curCol = nextCol;
curRow = nextRow;
return point;
});
if (points.length === 0)
return [stubPoint];
return points;
}
答案 0 :(得分:2)
边缘的控制点集由N个权重定义(w 1 ,w 2 ,... w N )和N个相应的距离(d 1 ,d 2 ,... d N )。
权重定义了点与源或目标的接近程度,距离控制点距离源 - 目标线的距离。距离的符号控制曲线所在的源 - 目标线的一侧(即手性)。有关详细信息,请参阅文档:http://js.cytoscape.org/#style/bezier-edges
为简单起见,下图总结了单个点的值,但您可以将其扩展到多个点:
请注意,上图为edge-distances: node-position
,而下图假定为edge-distances: intersection
(默认值):
对于复杂的用例,edge-distances: node-position
使计算更容易 - 但您必须更加小心,不要在节点体中指定点。这些例子的最终结果几乎相同,所以我没有更新曲线。不同大小的较大节点会使这些情况之间的差异更明显。
bezier控制点与控制点不相交。控制点"拉动"朝向这一点的曲线。对于像Cytoscape中的二次贝塞尔曲线,曲线的距离将是控制点的一半。有关贝塞尔人的更多信息,请参阅维基百科:https://en.wikipedia.org/wiki/B%C3%A9zier_curve
另一方面,分段边缘将与您指定的点相交,因为它们只是一系列直线:http://js.cytoscape.org/#style/segments-edges