antvis / layout

Layout algorithms for graphs.
206 stars 55 forks source link

GridLayout init model error: nodeSize is not a function or its return value is not iterable #78

Open vran-dev opened 2 years ago

vran-dev commented 2 years ago

问题描述

在使用 ANTV X6 集成 Layout ,使用 GridLayout 初始化模型数据时会出现异常:nodeSize is not a function or its return value is not iterable,尝试 Copy 官方源码实验也会出现同样的异常。

尝试使用 Dagre、Circle 的布局模式没有出现异常

版本依赖

场景复现

尝试将自定义的 er-rect 换成标准的 rect 依然报错

const graph = new Graph({
    container: document.getElementById('diagram-container'),
    grid: true,
    panning: true,
    snapline: true,
    selecting: {
        enabled: true,
        showNodeSelectionBox: true,
    },
    connecting: {
        snap: true,
        createEdge() {
            return graph.createEdge({
                shape: 'er-edge',
                strokeDasharray: 5,
                zIndex: 1
            })
        }
    },
})

const model = {
    nodes: [
        {
            "id":"departments",
            "shape":"er-rect",
            "size":{
                "width":224,
                "height":40
            },
            "width":224,
            "height":40,
            "label":"departments"
        }
    ],
    edges: []
}
const gridLayout = new GridLayout({
    type: 'grid',
})
const newModel = gridLayout.layout(model)   // throw error: nodeSize is not a function or its return value is not iterable
console.log(newModel)
graph.fromJSON(newModel)

异常日志

grid.js?8257:170 Uncaught (in promise) TypeError: nodeSize is not a function or its return value is not iterable
    at eval (grid.js?8257:170:1)
    at Array.forEach (<anonymous>)
    at GridLayout.execute (grid.js?8257:164:1)
    at GridLayout.layout (base.js?08f0:16:1)
    at Proxy.rendendarByAutoLayout (Diagram.vue?076d:179:1)
    at Proxy.init (Diagram.vue?076d:73:1)
    at Proxy.mounted (Diagram.vue?076d:67:1)
    at callWithErrorHandling (runtime-core.esm-bundler.js?d2dd:6737:1)
    at callWithAsyncErrorHandling (runtime-core.esm-bundler.js?d2dd:6746:1)
    at Array.hook.__weh.hook.__weh (runtime-core.esm-bundler.js?d2dd:1970:1)

报错代码片段

if (preventOverlap || paramNodeSpacing) {
    const nodeSpacing = getFuncByUnknownType(10, paramNodeSpacing);
    const nodeSize = getFuncByUnknownType(30, paramNodeSize, false);
    layoutNodes.forEach((node) => {
        if (!node.x || !node.y) {
            // for bb
            node.x = 0;
            node.y = 0;
        }
// ------------------------------------------------>
        const [nodew = 30, nodeh = 30] = nodeSize(node);  // nodeSize is not a function or its return value is not iterable
// <------------------------------------------------
        const p = nodeSpacing !== undefined ? nodeSpacing(node) : preventOverlapPadding;
        const w = nodew + p;
        const h = nodeh + p;
        self.cellWidth = Math.max(self.cellWidth, w);
        self.cellHeight = Math.max(self.cellHeight, h);
    });
}
wflixu commented 2 years ago

我也遇到了同样的问题,nodeSize(node) 返回的是数字,扩展赋值会报错。

Leridy commented 2 years ago

我也遇到了同样的问题,nodeSize(node) 返回的是数字,扩展赋值会报错。

499190982 commented 2 years ago

看了报错的源码,貌似可以在这写个方法 ,但是port的线条还是绞着的 @Leridy @wflixu const gridLayout = new GridLayout({ type: "grid", width: 600, height: 400, center: [300, 200], rows: 4, cols: 4, //自定义函数 nodeSize(node) { console.log("--node--", node); return [var_node_width, var_nodeHead_height + node.ports.length * var_nodePort_height]; }, });

Leridy commented 2 years ago

@499190982 我通过在实例化 GridLayout 的时候传入了 nodeSize 规避了这个报错

  const gridLayout = new GridLayout({
    type: "grid",
    width: 1000,
    height: 1000,
    cols: 4,
    rows: 4,
    nodeSize: [100, 100],
  });

至于port 线条绞着,我没有留意