基本网格布局未初始化或 运行

Basic Grid Layout not Initializing or Running

我正在尝试使用 cytoscape.js 在我的页面上显示图表,但我很难让基本实例正确显示。

代码分解:

我通过 AJAX 调用获取图形元素,将元素传递到 cytoscape 构造函数中,并在 Bootstrap 模态中显示实例。

这是我的 JavaScript:

var cy;

$.ajax({
                url : "getGraphElements",
                data : {
                    str : variableToGetCorrectGraphData
                },
                success : function(data) {
                    var elementsJson = JSON.parse(data.elements);
                    console.log(elementsJson);
                    
                    cy = cytoscape({
                        
                        container : document.getElementById('cy'),
                        
                        wheelSensitivity : 0.25,
                        
                        elements : elementsJson,
                        
                        style : [
                            {
                                selector: 'node',
                                style: 
                                {
                                    'background-color' : '#666',
                                    label : 'data(id)'
                                }
                            },
                            {
                                selector: 'edge',
                                style: 
                                {
                                    'width' : 3,
                                    'line-color' : '#737373',
                                    'target-arrow-color' : '#737373',
                                    'target-arrow-shape' : 'triangle',
                                    'curve-style' : 'bezier'
                                }
                            }
                        ],
                        layout : {
                            name: 'grid',
                            fit: true,                                                  // whether to fit the viewport to the graph
                            padding: 0,                                                 // padding used on fit
                            avoidOverlap: true,                                         // prevents node overlap, may overflow boundingBox if not enough space
                            avoidOverlapPadding: 20,                                    // extra spacing around nodes when avoidOverlap: true
                            nodeDimensionsIncludeLabels: false,                         // Excludes the label when calculating node bounding boxes for the layout algorithm
                            condense: false,                                            // uses all available space on false, uses minimal space on true
                            sort: function(a,b) {                                       // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }
                                return a.degree() - b.degree();
                            }, 
                            animate: false,                                             // whether to transition the node positions
                            transform: function (node, position ){ return position; }   // transform a given node position. Useful for changing flow direction in discrete layouts 
                        }
                    });

                    $('#cyModal').modal('show');
                }
            });
        });

这是我的 Bootstrap 模态:

<div class="modal fade bd-example-modal-lg" id="cyModal" tabindex="-1" role="dialog" aria-labelledby="cyModalLabel" aria-hidden="true">
  <div class="modal-dialog modal-lg">
    <div class="modal-content">
        <div class="modal-header">
            <button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">&times;</span> </button>
            <h4 class="modal-title" id="cyModalLabel">Graph View</h4>
        </div>
        <div class="modal-body">
            <div id="cy" style="height : 750px"></div>          
        </div>
    </div>
  </div>
</div>

这里是 AJAX 返回的 JSON 的示例(尽管我几乎可以肯定这不是错误的,因为所有元素似乎都出现在构造图中):

{ "nodes" : [{ "data" : { "id" : "12293"} }...], "edges" : [{ "data" : { "id" : "24607-26336", "source" : "24607", "target" : "26336" } }...] }

我的问题是当图表完成初始化时,所有节点都堆叠在左上角。我相信这是因为该实例正在使用 null 布局。快速查看检查器控制台显示 cy.layout.name = 'layout'.

我就是无法像我希望的那样使用网格布局对其进行初始化。我试过在构造函数中取出布局,并使用 cy.layout({name : 'grid',}).run();。我试过两者都用,一个接一个。我什至尝试将 cy.layout({name : 'grid',}).run(); 置于 while 循环中,直到 cy.layout.name == 'grid' - 这只会导致页面冻结。我尝试过基本上更改 Cytoscape 初始化程序和 Layout 初始化程序中的每个选项 - 没有骰子。我觉得奇怪的是,当我在检查器控制台中执行 cy.layout({name : 'grid',}).run(); 时,布局设置正确...

如果有人有任何想法,我将不胜感激!

好的,OP 在这里。我想我的问题是 Bootstrap.

我开始注意到我在完成 Cytoscape 实例的初始化后调用了 $('#cyModal').modal('show');。我意识到在我调用 $('#cyModal').modal('show'); 之前,我的 Cytoscape 实例的 div 容器没有大小并且是不可见的。所以我尝试在初始化 Cytoscape 之前调用 $('#cyModal').modal('show');,但仍然没有用。此外,我注意到直到 Cytoscape 初始化之后模态才真正显示出来。

显然,对于这种事情,我需要等待 Bootstrap 模式触发 'shown' 事件,然后再设置我的 Cytoscape 布局以确保 div 是可见并且有大小。所以我把我的布局 setter 放在 shown.bs.modal:

的监听​​器中
$('#cyModal').on('shown.bs.modal', function (e) {
    cy.layout({
        name: 'grid',
        fit: true,                                                  // whether to fit the viewport to the graph
        padding: 0,                                                 // padding used on fit
        avoidOverlap: true,                                         // prevents node overlap, may overflow boundingBox if not enough space
        avoidOverlapPadding: 20,                                    // extra spacing around nodes when avoidOverlap: true
        nodeDimensionsIncludeLabels: false,                         // Excludes the label when calculating node bounding boxes for the layout algorithm
        condense: false,                                            // uses all available space on false, uses minimal space on true
        sort: function(a,b) {                                       // a sorting function to order the nodes; e.g. function(a, b){ return a.data('weight') - b.data('weight') }
            return a.degree() - b.degree();
        }, 
        animate: false,                                             // whether to transition the node positions
        transform: function (node, position ){ return position; }   // transform a given node position. Useful for changing flow direction in discrete layouts
     }).run();
});

这对我有用,但感觉有点像 hack - 为什么我不能像我最初想的那样做?如果这就是饼干因 Cytoscape.js 和 Bootstrap 崩溃的方式 - 这就是生活;但如果有人有更多 'natural feeling' 解决方案,我会采纳任何其他建议。