Javascript 在cytoscape.js中使用网格布局时,复合节点重叠

Javascript 在cytoscape.js中使用网格布局时,复合节点重叠,javascript,visualization,grid-layout,cytoscape.js,Javascript,Visualization,Grid Layout,Cytoscape.js,我正在使用cytoscape.js进行我的可视化项目,在该项目中,我必须显示带有复合节点的层次结构 因此,我最初使用了Cose-Bilkent布局,它的工作方式很有魅力,但要求父节点的所有子节点必须位于一行中。所以我试着调整一下,但没有得到确切的结果 然后我尝试使用网格布局,给出了硬编码的行数和列数,得到了准确的结果,但由于我的数据是动态的,我意识到自己很难分配行数和列数 这是我使用的数据 elements: [ // list of graph elements to start with

我正在使用cytoscape.js进行我的可视化项目,在该项目中,我必须显示带有复合节点的层次结构

因此,我最初使用了Cose-Bilkent布局,它的工作方式很有魅力,但要求父节点的所有子节点必须位于一行中。所以我试着调整一下,但没有得到确切的结果

然后我尝试使用网格布局,给出了硬编码的行数和列数,得到了准确的结果,但由于我的数据是动态的,我意识到自己很难分配行数和列数

这是我使用的数据

elements: [ // list of graph elements to start with
            { // node a
                data: { id: 'X1', label: 'X1'}
            },
            {
                data: { id: 'X2', label: 'X2'}
            },
            {
                data: { id: 'X3', label: 'X3'}
            },
            {
                data: { id: 'X4', label: 'X4'}
            },
            {
                data: { id: 'X5', label: 'X5'}
            },
            {
                data: { id: 'X6', label: 'X6'}
            },
            {
                data: { id: 'X7', label: 'X7'}
            },
            {
                data: { id: 'X8', label: 'X8'}
            },
            {
                data: { id: 'X9', label: 'X9'}
            },
            {
                  data: { id: 'X10', label: 'X10'}
            },
            {
                data: { id: 'X1e1',label: 'e1', parent: 'X1', row: '1' ,col: '1'}
            },
            {
                data: { id: 'X1e5',label: 'e5', parent: 'X1', row: '1',col: '2'}
            },
            {
                data: { id: 'X1e6',label: 'e6', parent: 'X1', row: '1',col: '3'}
            },
            {
                data: { id: 'X2e2',label: 'e2', parent: 'X2', row: '3',col: '1'}
            },
            {
                data: { id: 'X2e3',label: 'e3', parent: 'X2', row: '3',col: '2'}
             },
            {
                data: { id: 'X3e4',label: 'e4', parent: 'X3', row: '4',col: '1'}
            },
            {
                data: { id: 'X4e5',label: 'e5', parent: 'X4', row: '2',col: '1'}
            },
            {
                data: { id: 'X4e6',label: 'e6', parent: 'X4', row: '2',col: '2'}
            },
            {
                data: { id: 'X5e7',label: 'e7', parent: 'X5', row: '7',col: '1'}
            },
            {
                data: { id: 'X6e8',label: 'e8', parent: 'X6', row: '5',col: '1'}
            },
            {
                data: { id: 'X6e9',label: 'e9', parent: 'X6', row: '5',col: '2'}
            },
            {
                data: { id: 'X7e10',label: 'e10', parent: 'X7', row: '7',col: '2'}
            },
            {
                data: { id: 'X7e11',label: 'e11', parent: 'X7', row: '7',col: '3'}
            },
            {
                data: { id: 'X7e12',label: 'e12', parent: 'X7', row: '7',col: '4'}
            },
            {
                data: { id: 'X8e13',label: 'e13', parent: 'X8', row: '6',col: '1'}
            },
            {
                data: { id: 'X8e14',label: 'e14', parent: 'X8', row: '6',col: '2'}
            },
            {
                data: { id: 'X8e15',label: 'e15', parent: 'X8', row: '6',col: '3'}
            },
            {
                data: { id: 'X8e16',label: 'e16', parent: 'X8', row: '6',col: '4'}
            },
            {
                data: { id: 'X9e17',label: 'e17', parent: 'X9', row: '8',col: '1'}
            },
            {
                data: { id: 'X10e18',label: 'e18', parent: 'X10', row: '8',col: '2'}
            },
            {
                data: { id: 'X1e5X4e5', source:'X1e5', target:'X4e5'}
            },
            {
                data: { id: 'X1e6X4e6', source:'X1e6', target:'X4e6'}
            },
            {
                data: { id: 'X1e1X2', source:'X1e1', target:'X2'}
            },
            {
                data: { id: 'X2e3X3', source:'X2e3', target:'X3'}
            },
            {
                data: { id: 'X4e5X5', source:'X4e5', target:'X5'}
            },
            {
                data: { id: 'X4e6X6', source:'X4e6', target:'X6'}
            },
            {
                data: { id: 'X6X8e16', source:'X6', target:'X8e16'}
            },
            {
                data: { id: 'X6e9X8', source:'X6e9', target:'X8'}
            },
            {
                data: { id: 'X6e8X7', source:'X6e8', target:'X7'}
            },
            {
                data: { id: 'X6X7e12', source:'X6', target:'X7e12'}
            }
        ]
和布局

layout:{
            name: 'grid',
            fit: true,
            position: function( node ){ return {row:node.data('row'), col:node.data('col') }} 
        }
下面是我通过设置手动行和列得到的结果(也是预期的结果)


任何帮助都将不胜感激。谢谢

有两个扩展,可以满足您的需要:

巧合的是,两者都来自同一个人,所以这根本不是问题,您需要做的就是应用正确的样式,使应用程序看起来像您的示例:

document.addEventListener(“DOMContentLoaded”,function()){
var cy=(window.cy=cytoscape)({
容器:document.getElementById(“cy”),
布局:{
姓名:“父母”
},
风格:[{
选择器:“节点”,
风格:{
“内容”:“数据(id)”,
“背景色”:“ad1a66”
}
},
{
选择器:“:父项”,
风格:{
“背景不透明度”:0.333
}
},
{
选择器:“边缘”,
风格:{
宽度:3,
“线条颜色”:“ad1a66”
}
},
{
选择器:“edge.meta”,
风格:{
宽度:2,
“线条颜色”:“红色”
}
},
{
选择器:“:已选定”,
风格:{
“边界宽度”:3,
“边框颜色”:“DAA520”
}
}
],
要素:{
节点:[{
数据:{
id:“杰瑞”,
姓名:“杰瑞”
}
},
{
数据:{
id:“伊莲”,
姓名:“伊莲”
}
},
{
数据:{
id:“克莱默”,
名字:“克莱默”
}
},
{
数据:{
id:“乔治”,
姓名:“乔治”
}
},
{
数据:{
id:“马丁”,
姓名:“马丁”
}
},
{
数据:{
id:“菲利普”,
姓名:“菲利普”
}
},
{
数据:{
id:“路易斯”,
姓名:“路易斯”
}
},
{
数据:{
id:“Genevieve”,
姓名:“Genevieve”
}
},
{
数据:{
id:“狮子座”,
名字:“狮子座”
}
},
{
数据:{
id:“拉里”,
姓名:“拉里”
}
},
{
数据:{
id:“洛盖纳”,
姓名:“洛盖纳”
}
}
],
边缘:[{
数据:{
资料来源:“Jerry”,
目标:“伊莲”
}
},
{
数据:{
资料来源:“Jerry”,
目标:“克莱默”
}
},
{
数据:{
资料来源:“Jerry”,
目标:“乔治”
}
},
{
数据:{
资料来源:“伊莱恩”,
目标:“马丁”
}
},
{
数据:{
资料来源:“伊莱恩”,
目标:“菲利普”
}
},
{
数据:{
资料来源:“伊莱恩”,
目标:“路易斯”
}
},
{
数据:{
资料来源:“伊莱恩”,
目标:“Genevieve”
}
},
{
数据:{
资料来源:“伊莱恩”,
目标:“狮子座”
}
},
{
数据:{
资料来源:“克莱默”,
目标:“拉里”
}
},
{
数据:{
资料来源:“克莱默”,
目标:“洛盖纳”
}
}
]
}
}));
//演示你的收藏
cy.nodes().noOverlap({
填充:5
});
});
正文{
字体:14px helvetica neue,helvetica,arial,无衬线;
}
#赛义德{
身高:100%;
宽度:100%;
位置:绝对位置;
左:0;
排名:0;
}

以下代码对我有效

如果这不起作用,请考虑史蒂芬的代码。< /P>
var cy = cytoscape({
    container: /* your div within which you want to render */ ,
    elements: [ /*list of graph elements to start with */ ] ,
    style: [ /* the stylesheet for the graph */ ] ,
    layout:{
                name: 'cola',
                fit: false,
                infinite: false,
                avoidOverlap: true
            }
});

//Used to make child nodes stay on the same row
cy.ready(function(){
                setTimeout(function(){
                    cy.zoom(0.5);
                    cy.nodes(':compound').forEach(function(comp,j,comps){
                        var nodePosition={};
                        if(comp.descendants().length>1)
                        {
                            var minX;
                            var maxY;
                            comp.descendants().forEach(function(ele,i,eles){
                                if(i==0)
                                {
                                    minX=ele.renderedPosition('x');
                                    maxY=ele.renderedPosition('y');
                                }
                                else
                                {
                                    var tempX=ele.renderedPosition('x');
                                    var tempY=ele.renderedPosition('y');
                                    if(tempX<minX)
                                    {
                                        minX=tempX;
                                    }
                                    if(tempY>maxY)
                                    {
                                        maxY=tempY;
                                    }
                                }
                            });
                            comp.descendants().forEach(function(ele,i,eles){
                                ele.renderedPosition({x:minX,y:maxY});
                                minX=minX+60;
                            });
                        }
                        cy.resize();
                        cy.fit();
                        cy.minZoom(cy.zoom());
                    });
                },1000);
            });
var cy=cytoscape({
容器:/*要在其中渲染的div*/,
元素:[/*以*/]开头的图形元素列表,
样式:[/*图形的样式表*/],
布局:{
名字:“可乐”,
fit:false,
无限:错,
avoidOverlap:对
}
});
//用于使子节点保持在同一行上
cy.ready(函数(){
setTimeout(函数(){
cy.zoom(0.5);
cy.nodes(':component').forEach(函数(comp,j,comps){
var nodePosition={};
如果(组件子体()长度>1)
{
var-minX;
var-maxY;
comp.subjects().forEach(函数(ele,i,eles){
如果(i==0)
{
minX=ele.renderedPosition('x');
maxY=元素渲染位置(“y”);
}
其他的
{
var tempX=ele.renderedPosition('x');
变量