Я не могу получить Cytoscape. js для отображения моего графика на всех - PullRequest
3 голосов
/ 16 марта 2020

Я построил диаграмму на веб-странице с помощью программы JavaScript Cytoscape. js. Он вообще ничего не отображает. Но это также не дает синтаксических ошибок, кроме предупреждения о захвате мыши для масштабирования.

Вот код:

     <style type="text/css">
        #cy {
            width: 90%;
            height: 300px;
            display: block;
        }
    </style>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.14.0/cytoscape.min.js"></script>
    <script type="text/javascript">
        var cy = cytoscape({

            container: document.getElementById('cy'), // container to render in


            style: [ // the stylesheet for the graph
                {
                    selector: 'node',
                    style: {
                        'background-color': '#666',
                        'label': 'data(id)'
                    }
                },

                {
                    selector: 'edge',
                    style: {
                        'width': 3,
                        'line-color': '#ccc',
                        'target-arrow-color': '#ccc',
                        'target-arrow-shape': 'triangle'
                    }
                }
            ],


            // initial viewport state:
            zoom: 1,
            pan: { x: 0, y: 0 },

            // interaction options:
            minZoom: 1e-50,
            maxZoom: 1e50,
            zoomingEnabled: true,
            userZoomingEnabled: true,
            panningEnabled: true,
            userPanningEnabled: true,
            boxSelectionEnabled: true,
            selectionType: 'single',
            touchTapThreshold: 8,
            desktopTapThreshold: 4,
            autolock: false,
            autoungrabify: false,
            autounselectify: false,

            // rendering options:
            headless: false,
            styleEnabled: true,
            hideEdgesOnViewport: false,
            textureOnViewport: false,
            motionBlur: false,
            motionBlurOpacity: 0.2,
            wheelSensitivity: 1,
            pixelRatio: 'auto'
        });
        let options = {
            name: 'breadthfirst',

            fit: true, // whether to fit the viewport to the graph
            directed: false, // whether the tree is directed downwards (or edges can point in any direction if false)
            padding: 30, // padding on fit
            circle: false, // put depths in concentric circles if true, put depths top down if false
            grid: false, // whether to create an even grid into which the DAG is placed (circle:false only)
            spacingFactor: 1.75, // positive spacing factor, larger => more space between nodes (N.B. n/a if causes overlap)
            boundingBox: undefined, // constrain layout bounds; { x1, y1, x2, y2 } or { x1, y1, w, h }
            avoidOverlap: true, // prevents node overlap, may overflow boundingBox if not enough space
            nodeDimensionsIncludeLabels: false, // Excludes the label when calculating node bounding boxes for the layout algorithm
            roots: undefined, // the roots of the trees
            maximal: false, // whether to shift nodes down their natural BFS depths in order to avoid upwards edges (DAGS only)
            animate: false, // whether to transition the node positions
            animationDuration: 500, // duration of animation in ms if enabled
            animationEasing: undefined, // easing of animation if enabled,
            animateFilter: function (node, i) { return true; }, // a function that determines whether the node should be animated.  All nodes animated by default on animate enabled.  Non-animated nodes are positioned immediately when the layout starts
            ready: undefined, // callback on layoutready
            stop: undefined, // callback on layoutstop
            transform: function (node, position) { return position; } // transform a given node position. Useful for changing flow direction in discrete layouts
        };

        cy.layout(options);
var eles1 = cy.add([
{ group: 'nodes', data: { id: 'E1'} },
{ group: 'nodes', data: { id: 'E2'} },
{ group: 'nodes', data: { id: 'E3'} },
{ group: 'nodes', data: { id: 'E4'} },
{ group: 'nodes', data: { id: 'E5'} },
{ group: 'nodes', data: { id: 'E6'} },
{ group: 'nodes', data: { id: 'E7'} },
{ group: 'nodes', data: { id: 'E8'} }  ]);
var eles2 = cy.add([
{ group: 'nodes', data: { id: 'LH1'} },
{ group: 'nodes', data: { id: 'RH1'} },
{ group: 'nodes', data: { id: 'LH2'} },
{ group: 'nodes', data: { id: 'LH3'} },
{ group: 'nodes', data: { id: 'RH2'} },
{ group: 'nodes', data: { id: 'LH4'} },
{ group: 'nodes', data: { id: 'RH3'} },
{ group: 'nodes', data: { id: 'RH4'} } ]);
var eles4 = cy.add([
{ group: 'edges', data: { id: 'edge0', source: 'E4', target: 'E5' } },
{ group: 'edges', data: { id: 'edge1', source: 'E6', target: 'E7' } },
{ group: 'edges', data: { id: 'edge2', source: 'LH1', target: 'E1' } },
{ group: 'edges', data: { id: 'edge3', source: 'LH1', target: 'RH1' } },
{ group: 'edges', data: { id: 'edge4', source: 'LH2', target: 'E4' } },
{ group: 'edges', data: { id: 'edge5', source: 'LH3', target: 'E4' } },
{ group: 'edges', data: { id: 'edge6', source: 'LH4', target: 'E6' } },
{ group: 'edges', data: { id: 'edge7', source: 'RH1', target: 'E2' } },
{ group: 'edges', data: { id: 'edge8', source: 'RH1', target: 'E3' } },
{ group: 'edges', data: { id: 'edge9', source: 'RH2', target: 'E5' } },
{ group: 'edges', data: { id: 'edge10', source: 'RH3', target: 'E7' } },
{ group: 'edges', data: { id: 'edge11', source: 'RH4', target: 'E8' } }  ]);

</script>

    <center>

        <div id="cy"  >
        </div>

    </center>

Мой код фактически сгенерирован в asp. net, но это не должно иметь значения.

1 Ответ

3 голосов
/ 16 марта 2020

Вы добавляете элементы на график после запуска макета. Вот почему все ваши узлы накапливаются в верхнем левом углу.

У вас есть два варианта здесь:

  1. Предоставить оба макета для элементов конструктора.
  2. Сначала инициализируйте график, затем добавьте элементы (например, с помощью cy.json()), а затем скажите cytoscape для запуска макета с cy.layout(...).run().

Документация для cy.layout() здесь , а для cy.json() здесь .

Следующий фрагмент использует первый подход, но я оставил второй комментарий закомментированным на случай, если вы не можете предоставить элементы в вызове конструктора (т. е. если вам нужно получить их асинхронно).

var nodeArray = [
  { group: 'nodes', data: { id: 'E1'} },
  { group: 'nodes', data: { id: 'E2'} },
  { group: 'nodes', data: { id: 'E3'} },
  { group: 'nodes', data: { id: 'E4'} },
  { group: 'nodes', data: { id: 'E5'} },
  { group: 'nodes', data: { id: 'E6'} },
  { group: 'nodes', data: { id: 'E7'} },
  { group: 'nodes', data: { id: 'E8'} },
  { group: 'nodes', data: { id: 'LH1'} },
  { group: 'nodes', data: { id: 'RH1'} },
  { group: 'nodes', data: { id: 'LH2'} },
  { group: 'nodes', data: { id: 'LH3'} },
  { group: 'nodes', data: { id: 'RH2'} },
  { group: 'nodes', data: { id: 'LH4'} },
  { group: 'nodes', data: { id: 'RH3'} },
  { group: 'nodes', data: { id: 'RH4'} }
];

var edgeArray = [
  { group: 'edges', data: { id: 'edge0', source: 'E4', target: 'E5' } },
  { group: 'edges', data: { id: 'edge1', source: 'E6', target: 'E7' } },
  { group: 'edges', data: { id: 'edge2', source: 'LH1', target: 'E1' } },
  { group: 'edges', data: { id: 'edge3', source: 'LH1', target: 'RH1' } },
  { group: 'edges', data: { id: 'edge4', source: 'LH2', target: 'E4' } },
  { group: 'edges', data: { id: 'edge5', source: 'LH3', target: 'E4' } },
  { group: 'edges', data: { id: 'edge6', source: 'LH4', target: 'E6' } },
  { group: 'edges', data: { id: 'edge7', source: 'RH1', target: 'E2' } },
  { group: 'edges', data: { id: 'edge8', source: 'RH1', target: 'E3' } },
  { group: 'edges', data: { id: 'edge9', source: 'RH2', target: 'E5' } },
  { group: 'edges', data: { id: 'edge10', source: 'RH3', target: 'E7' } },
  { group: 'edges', data: { id: 'edge11', source: 'RH4', target: 'E8' } }
];

var stylesArray = [{
  selector: 'node',
  style: {
    'background-color': '#666',
    'label': 'data(id)'
  }
},{
  selector: 'edge',
  style: {
    'width': 3,
    'line-color': '#ccc',
    'target-arrow-color': '#ccc',
    'target-arrow-shape': 'triangle'
  }
}];

var layout = {name: 'breadthfirst'};

// You used mostly default options, there's no need to redefine them
var cy = cytoscape({
  container: document.getElementById('cy'),
  style: stylesArray,
  // If you want to apply the layout on the constructor
  // you must supply the elements too
  layout: layout,
  elements: {
    nodes: nodeArray,
    edges: edgeArray
  }
});

// Or add the elements afterwards, it's your choice
// But then you need to re-run the layout
/*
cy.json({
  elements: {
    nodes: nodeArray,
    edges: edgeArray
  }
});

// Tell cytoscape to apply the layout when ready
cy.ready(function () {
  cy.layout(layout).run();
});
*/
 #cy {
   width: 90%;
   height: 300px;
   display: block;
 }
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.14.0/cytoscape.min.js"></script>
<div id="cy"></div>
...