🤔思考 g6 流程图锚点(anchor)到底怎么才能固定住,我是这样做的。| 🏆 技术专题第三期征文

6,112 阅读3分钟

下面这些是 G6 能够实现的自定义节点。

当去拖拽其中一个节点的时候,结果就会像下图这样子。不论换到哪个方向,始终是取两个节点之最近的锚点来进行连线最近距离进行绘制。

这是因为 g6 的锚点默认的逼近策略导致的,虽然这种策略虽然是合理的,但是我还是想要避开这个策略😂。让线的两边固定在锚点上,不论节点怎么拖动,这两条线的出发点不会变化。

从 data 的角度考虑🤔

用现在已有的数据来看,并没有能够体现出指定锚点出发以及指定锚点结束的地方。

假如像这样子指定从第几个锚点出发,也是方法之一。不过如果每个节点的锚点个数不确定,或者锚点在节点之外的地方就不容易画出来了。

方法的话有很多,在语雀文档上大家也都有讨论,大家可以移步去看看。这次我决定用下面偏移坐标这种写法。

首先这么写可以表达从哪里出发,从哪里结束。其次代码实现思路简单,直接加上偏移值就可以了。但是需要把原有上下左右 4 个锚点改成为一个锚点 [0.5, 0.5],如果没有偏移值的时候会变成中间连在中间,并且看不到箭头。

代码实现

实现自定义线条

线条的绘制思路,自定义线条的 draw 方法,可以拿到起始点(startPoint)和结束点(endPoint),对两个点进行一个偏移即可。

const data = {
    // 边集
    edges: [
        {
            source: 'node1', // String,必须,起始点 id
            target: 'node2', // String,必须,目标点 id
            startOffsetX: 0, // 起始点偏离的 X
            startOffsetY: 35, // 起始点偏离的 Y
            endOffsetX: 0, // 终点偏离的 X
            endOffsetY: -35 // 终点偏离的 Y
        }
    ]
}
// 自定义线条
G6.registerEdge('edge-flow', {
    draw (cfg, group) {
        let start = cfg.startPoint
        let end = cfg.endPoint
        // 起始点偏移
        start = {
          x: start.x + (cfg.startOffsetX || 0),
          y: start.y + (cfg.startOffsetY || 0)
        }
        // 结束点偏移
        end = {
          x: end.x + (cfg.endOffsetX || 0),
          y: end.y + (cfg.endOffsetY || 0)
        }
        // ...
    }
})

实现自定义节点

定义好锚点的数据,指定 offset 位置。

const graph = new G6.Graph({
    // ...
    defaultNode: {
        shape: 'node-flow',
        anchors: [
            { offsetX: 0, offsetY: 35 },
            { offsetX: 35, offsetY: 0 },
            { offsetX: 0, offsetY: -35 },
            { offsetX: -35, offsetY: 0 }
        ]
    }
})

根据数据绘制出锚点。

G6.registerNode('node-flow', {
    // ...
    afterDraw (cfg, group) {
        this.drawAnchor(cfg, group)
    },
    drawAnchor (cfg, group) {
        // 绘制出所有的锚点
        anchors.forEach(anchor => {
            group.addShape('circle', {
                attrs: {
                    x: anchor.offsetX,
                    y: anchor.offsetY,
                    r: 5,
                    fill: '#fff',
                    stroke: '#9B43E7',
                    cursor: 'pointer'
                }
            })
        })
    },
    // 定义锚点位置在中心
    getAnchorPoints () {
        return [
            [ 0.5, 0.5 ]
        ]
    }
})

绘制好以后,效果就是开头所说的那个样子。

最后

在 g6 的语雀和搜索引擎,徘徊了好久,都没有找到有文章提到怎么固定锚点的做法,不知道是不是我搜索姿势不对,后来思考出了一个想法之后,便有了这篇文章。在这篇文章里提供一种解决思路就是偏移线条的开始结束点,并且代码也实现了一遍,有需要参考的可以去逛下文章 github 地址。

另外,这篇文章并没有提到自定义连线和自定义拖拽这两种自定义行为,因为跟文章关系不是很大,所以就先不提了。


demo:https://viewweiwu.github.io/g6-flow/
code:https://github.com/viewweiwu/g6-flow

🏆 技术专题第三期 | 数据可视化的那些事......