Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

边与边的连接 #2027

Closed
gvcode1 opened this issue Apr 20, 2022 · 14 comments
Closed

边与边的连接 #2027

gvcode1 opened this issue Apr 20, 2022 · 14 comments
Assignees
Labels
type: discussion 讨论 Usage questions, guidance, and other discussions

Comments

@gvcode1
Copy link

gvcode1 commented Apr 20, 2022

功能描述

目前我们在尝试用X6做的电路图设计应用,有大量的边与边的连接场景,请教下目前这种功能支持吗,或者后续会有计划考虑增强吗:
图片

期望解决方案

希望可以边与边能够建立连接,并且在边任意指定的间距上都可以连接,其内部逻辑关系可以通过API或者属性拿到。

@NewByVector
Copy link
Contributor

边之前是可以连接的,添加边的时候 source 或者 target 指定为边的 id 就可以了。

@NewByVector NewByVector self-assigned this Apr 21, 2022
@NewByVector NewByVector added the type: discussion 讨论 Usage questions, guidance, and other discussions label Apr 21, 2022
@gvcode1
Copy link
Author

gvcode1 commented Apr 21, 2022

非常感谢答复,边的ID指定的话,但是连接点的位置好像不能指定额,可以看这几个点,同一条边上在不同的位置,可以分别与多个边连接。

我们想实现的效果是拖动边的端点,到另外一条边上鼠标放开,然后就在鼠标放开的地方建立连接,并有一个黑色的点表示已经连接上,同一条边上任意位置都可以这样实现这样效果。相当于在边上实际上可以动态增加对应位置的连接桩,该连接桩如果没有额外的边连接后,黑点自动删除。

整体效果用程序可以控制,包括鼠标拖拽,但是可能需要鼠标移动到边上的事件(返回鼠标移动到边上的位置,可以是相对这条边的起始位置,然后通过接口创建连接桩,此时松开鼠标左键的话,就默认建立连接),

带编辑功能的流程图可能都会碰到类似的问题呢,边与边的连接是希望在任意的位置连接,这一点文档里面查询不到。

另外节点的连接桩已经很开放了,可以随意定制,边的话目前还是有点挑战。

图片

@lyon-liao
Copy link

lyon-liao commented Apr 21, 2022

@gvcode1 X6 目前有两种锚点可以指定位置。
ratio 默认值,锚点位于被连接的边的指定比例处。
length 锚点位于被连接的边的指定长度处。

如何计算ratio 和length

const edgeView = <EdgeView>edge.findView(this.graph) // edge 为目标线
const length = edgeView.getClosestPointLength(point) // point 为你想链接到线上的坐标点

Tips: 计算ratio 同理,有相应的方法

以上方案不知是不是最佳实践,我是看源码找到的方案。

@gvcode1
Copy link
Author

gvcode1 commented Apr 21, 2022

@lyon-liao 刚才查了下文档中的Edge的属性,没有看到锚点定义呢,有vertices路径点,但是这个似乎无法进行edge连接

@lyon-liao
Copy link

lyon-liao commented Apr 21, 2022

@gvcode1 可以连接的,只不过有些BUG。
Bugs: 2024 2035
需要些配置信息 connecting

// this.node 是 Edge
connectToLine(line: OLine, point: PositionLike, endType: 'source' | 'target') {
    const seter = endType === 'source' ? this.node!.setSource : this.node!.setTarget
    const edgeView = <EdgeView>line.node!.findView(this.editor.graph)
    const length = edgeView.getClosestPointLength(point)
    seter.apply(this.node, [line.node, {anchor: {name: 'length',  args: {length}}}] as any)
}

@gvcode1
Copy link
Author

gvcode1 commented Apr 21, 2022

@lyon-liao 非常感谢,我漏掉了API文档,看如下示例以及实验下就可以确定边连接边,并且可以有不同的锚点
https://x6.antv.vision/zh/docs/api/registry/edge-anchor

理论上是可以满足要求。但是要实现这种电路图编辑需求,感觉还是很多工作,不太容易。。。

@gvcode1 gvcode1 closed this as completed Apr 21, 2022
@lyon-liao
Copy link

@gvcode1 我正在做的事情和你的很相似。头痛

@oyal
Copy link

oyal commented Mar 22, 2023

我也有类似的需求,没有好的解决方案

@oyal
Copy link

oyal commented Feb 20, 2024

@gvcode1 X6 目前有两种锚点可以指定位置。 ratio 默认值,锚点位于被连接的边的指定比例处。 length 锚点位于被连接的边的指定长度处。

如何计算ratio 和length

const edgeView = <EdgeView>edge.findView(this.graph) // edge 为目标线
const length = edgeView.getClosestPointLength(point) // point 为你想链接到线上的坐标点

Tips: 计算ratio 同理,有相应的方法

以上方案不知是不是最佳实践,我是看源码找到的方案。

非常好的思路,同时开启自动吸附 snap 和 允许连接到边 allowEdge 会自动吸附到边的中间,我通过修改 EdgeView 可以使用你的这种方式来解决

默认情况:

recording

修改后:

recording

找到 x6/packages/x6/src/view/edge.tssnapArrowhead 方法,修改后:

if (closestView) {
  if (!changed && !closestView.isEdgeView()) {
    return
  }
  closestView.highlight(closestMagnet, {
    type: 'magnetAdsorbed',
  })
  if (closestView.isEdgeView()) {
    this.cell.setTarget(
      closestView.getEdgeTerminal(closestMagnet, x, y, this.cell, type),
    )
    const length = closestView.getClosestPointLength({ x, y })
    this.cell.prop('target/anchor', {
      name: 'length',
      args: {
        length,
      },
    })
    return
  } else {
    terminal = closestView.getEdgeTerminal(
      closestMagnet,
      x,
      y,
      this.cell,
      type,
    )
  }
} else {
  terminal = { x, y }
}

@gvcode1
Copy link
Author

gvcode1 commented Feb 20, 2024

@gvcode1 X6 目前有两种锚点可以指定位置。 ratio 默认值,锚点位于被连接的边的指定比例处。 length 锚点位于被连接的边的指定长度处。
如何计算ratio 和length

const edgeView = <EdgeView>edge.findView(this.graph) // edge 为目标线
const length = edgeView.getClosestPointLength(point) // point 为你想链接到线上的坐标点

Tips: 计算ratio 同理,有相应的方法
以上方案不知是不是最佳实践,我是看源码找到的方案。

非常好的思路,同时开启自动吸附 snap 和 允许连接到边 allowEdge 会自动吸附到边的中间,我通过修改 EdgeView 可以使用你的这种方式来解决

默认情况:

recording recording

修改后:

recording recording

找到 x6/packages/x6/src/view/edge.tssnapArrowhead 方法,修改后:

if (closestView) {
  if (!changed && !closestView.isEdgeView()) {
    return
  }
  closestView.highlight(closestMagnet, {
    type: 'magnetAdsorbed',
  })
  if (closestView.isEdgeView()) {
    this.cell.setTarget(
      closestView.getEdgeTerminal(closestMagnet, x, y, this.cell, type),
    )
    const length = closestView.getClosestPointLength({ x, y })
    this.cell.prop('target/anchor', {
      name: 'length',
      args: {
        length,
      },
    })
    return
  } else {
    terminal = closestView.getEdgeTerminal(
      closestMagnet,
      x,
      y,
      this.cell,
      type,
    )
  }
} else {
  terminal = { x, y }
}

太感谢了,就是这个功能!!

@oyal
Copy link

oyal commented Feb 20, 2024

@gvcode1 这样使用,写一个类继承 EdgeView,重写 snapArrowhead 方法,然后在 createCellView 覆盖

2024-02-20_15-56-04

new Graph({
  // ...
  createCellView(cell) {
    if (cell.isEdge()) {
      return MyEdgeView
    }
  },
})

@oyal
Copy link

oyal commented Feb 20, 2024

锚点效果也不太好,我目前是在连接成功后,将原有边删除,然后创建一个节点,三个新的边,实现起来也比较麻烦,不够友好

recording

@gvcode1
Copy link
Author

gvcode1 commented Feb 20, 2024

锚点效果也不太好,我目前是在连接成功后,将原有边删除,然后创建一个节点,三个新的边,实现起来也比较麻烦,不够友好

recording recording

一条边的锚点可以有多个吗?单独创建一个点的确有点小麻烦。

@oyal
Copy link

oyal commented Feb 20, 2024

锚点效果也不太好,我目前是在连接成功后,将原有边删除,然后创建一个节点,三个新的边,实现起来也比较麻烦,不够友好

recording recording

一条边的锚点可以有多个吗?单独创建一个点的确有点小麻烦。

可以有多个不影响,锚点是固定在制定比例或者长度处,想要再次修改位置的话应该要使用线条工具了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
type: discussion 讨论 Usage questions, guidance, and other discussions
Projects
None yet
Development

No branches or pull requests

4 participants