g6解决拓扑图中dagre布局需要增加同级节点的问题(旁挂层同级节点相连)

背景:dagre可以在节点数据中配置layer字段,为节点指定层级,但layer的指定不能违背图结构与层次布局的原则,也就是说每一条边的起点的layer一定小于终点的layer值,否则会导致布局失败。

解决办法:动态添加节点,在需要增加同级节点的node处添加一个影子节点,隐藏该影子节点,将需要添加的节点动态添加到该影子节点上。

示例图:
在这里插入图片描述

代码如下:

import G6 from '@antv/g6';
import insertCss from 'insert-css';

insertCss(`
  .g6-tooltip {
    border-radius: 6px;
    font-size: 12px;
    color: #fff;
    background-color: #000;
    padding: 2px 8px;
    text-align: center;
  }
`);

const data = {
  nodes: [
    {
      id: '1',
      dataType: 'alps',
      name: '1',
      layer:0
    },
    {
      id: '2',
      dataType: 'alps',
      name: '2',
      layer:0
    },
    {
      id: '3',
      dataType: 'alps',
      name: '3',
      layer:1
    },
     {
      id: '6',
      dataType: 'sql2',
      name: '6',
      layer:3
    },
     {
      id: '7',
      dataType: 'sql2',
      name: '7',
      layer:3
    },
    
  ],
  edges: [
    {
      source: '2',
      target: '3',
    },
    {
      source: '1',
      target: '3',
    },
    {
      source: '3',
      target: '6',
    },
    {
      source: '3',
      target: '7',
    },

  ],
};

G6.registerNode(
  'sql',
  {
    drawShape(cfg, group) {
      const rect = group.addShape('rect', {
        attrs: {
          x: -75,
          y: -25,
          width: 150,
          height: 50,
          radius: 10,
          stroke: '#5B8FF9',
          fill: '#C6E5FF',
          lineWidth: 3,
        },
        name: 'rect-shape',
      });
      if (cfg.name) {
        group.addShape('text', {
          attrs: {
            text: cfg.name,
            x: 0,
            y: 0,
            fill: '#00287E',
            fontSize: 14,
            textAlign: 'center',
            textBaseline: 'middle',
            fontWeight: 'bold',
          },
          name: 'text-shape',
        });
      }
      return rect;
    },
  },
  'single-node',
);

const container = document.getElementById('container');
const width = container.scrollWidth;
const height = container.scrollHeight || 500;
const graph = new G6.Graph({
  container: 'container',
  width,
  height,
  layout: {
    type: 'dagre',
    ranksep: 70,
    controlPoints: true, 
  },
  defaultNode: {
    type: 'sql',
    size: [48, 48],
     anchorPoints: [
          // [0, 0],代表节点左上角的锚点,[1, 1],代表节点右下角的锚点。
          [0.5, 0], // 顶部中心锚点
          [0.5, 1], // 底部中心锚点
        ],
  },
  defaultEdge: {
    type: 'cubic-vertical',
    sourceAnchor: 1,
    style: {
      // radius: 20,
      // offset: 45,
      // endArrow: true,
      lineWidth: 1,
      stroke: '#C9CDD4',
      shadowBlur: 10,
    },
  },
  nodeStateStyles: {
    selected: {
      stroke: '#d9d9d9',
      fill: '#5394ef',
    },
  },
  modes: {
    default: [
      'drag-canvas',
      'zoom-canvas',
      'click-select',

    ],
  },
  fitView: true,
});
graph.data(data);
graph.render();
graph.on('afterrender',()=>{
  const targerNode = graph.findById('3');
  const realModel = targerNode.getModel();
  graph.addItem("node", {
      id: 'shadowNode',
      x: realModel.x,
      y: realModel.y,
      label: '影子节点',
      anchorPoints: [[0, 0.5], [1, 0.5]],
    });
  graph.findById('shadowNode').hide();
  graph.addItem("node", {
      id: 'add1',
      x: realModel.x + 200 + 20 * 3,
      y: realModel.y,
      label: '额外节点',
      anchorPoints: [[0.5, 0], [0.5, 0]]
    });
     graph.addItem("edge", {
      source: 'shadowNode',
      target: 'add1',
      type: 'arc',
    });
     graph.addItem("node", {
      id: 'add11',
      x: realModel.x + 400 + 20 * 3,
      y: realModel.y,
      label: '额外节点2',
      anchorPoints: [[0.5, 0], [0.5, 0]]
    });
    graph.addItem("edge", {
      source: 'shadowNode',
      target: 'add11',
      type: 'arc',
    });
})
if (typeof window !== 'undefined')
  window.onresize = () => {
    if (!graph || graph.get('destroyed')) return;
    if (!container || !container.scrollWidth || !container.scrollHeight) return;
    graph.changeSize(container.scrollWidth, container.scrollHeight);
  };

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要动态增加节点的背景图片,你可以使用 G6 提供的 `update` 方法。具体步骤如下: 1. 定义节点的样式,包括背景图片和其他属性: ```javascript const nodeStyle = { keyshape: { fill: "white", stroke: "#5B8FF9", lineWidth: 2 }, label: { fontSize: 12, fill: "black", textAlign: "center", textBaseline: "middle" }, backgroundImage: { img: "", width: 40, height: 40, x: -20, y: -20 } }; ``` 其,`backgroundImage` 属性用于设置节点的背景图片,`img` 属性表示图片的地址,`width` 和 `height` 属性表示图片的宽度和高度,`x` 和 `y` 属性表示图片的位置偏移量。 2. 在节点数据添加背景图片地址: ```javascript const node = { id: "node1", x: 100, y: 100, label: "Node 1", backgroundImage: { img: "https://cdn.example.com/background.jpg" } }; ``` 3. 在渲染节点时,将节点的 `backgroundImage` 属性更新到样式: ```javascript const node = graph.addNode({ id: "node1", x: 100, y: 100, label: "Node 1" }); graph.updateItem(node, { ...nodeStyle, backgroundImage: { ...nodeStyle.backgroundImage, img: node.getModel().backgroundImage.img } }); ``` 在上面的代码,我们使用 `updateItem` 方法将节点的样式更新为 `nodeStyle`,同时将 `backgroundImage` 属性的图片地址更新为节点数据的地址。 4. 当节点的背景图片地址发生变化时,重新调用 `updateItem` 方法更新节点的样式: ```javascript const node = graph.findById("node1"); node.getModel().backgroundImage.img = "https://cdn.example.com/new-background.jpg"; graph.updateItem(node, { ...nodeStyle, backgroundImage: { ...nodeStyle.backgroundImage, img: node.getModel().backgroundImage.img } }); ``` 当节点的 `backgroundImage` 属性的图片地址发生变化时,我们可以通过节点的 ID 查找到节点,并更新节点的样式。这里我们将节点数据的 `backgroundImage.img` 属性更新为新的图片地址,然后再次调用 `updateItem` 方法更新节点的样式。 以上就是动态增加节点背景图片的方法。希望对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值