2

I'm using Cytoscape to generate a simple flow/state diagram and I'm able to generate the graph, but as the graph grows, it just keeps zooming out so the nodes become really small. Is there a way to have Cytoscape to just keep growing in height instead of shrinking the graph and having to zoom in? I would rather have the nodes stay a known size (i.e. 100px X 100px) and as the graph grows and have it grow vertically so the user just has to scroll down the page to see the rest of the graph. Right now, the viewport is restricted to the height of the page when the page is first rendered. Let me know if there is a way to achieve a vertically scrolling graph with fixed size nodes. Thanks!

Andrew Serff
  • 2,117
  • 4
  • 21
  • 32
  • 1
    You can make your question less abstract and make it more answerable by providing a [Help Center > Asking > How to create a Minimal, Complete, and Verifiable example](http://stackoverflow.com/help/mcve). [JSFiddle](http://jsfiddle.net/) would be a good move. Meanwhile, did you try plaing with http://js.cytoscape.org/#core/viewport-manipulation/cy.zoomingEnabled ? – xmojmr Dec 11 '14 at 16:50
  • 1
    Yes, disabling zooming gets the nodes back to the size I want them, but doesn't help the viewport issue. I've started trying to dynamically determine what the height should be, but not sure what to do if you add nodes (i.e. the viewport needs to grow again.). Will update once I try some of these ideas out – Andrew Serff Dec 11 '14 at 18:15

3 Answers3

3

Based on the suggestions of maxkfranz and gcpdev, I came up with the following solution that seems to work pretty well.

Cytoscope Init:

cy = cytoscape({
    container: document.getElementById('cy'),
    style: cytoscape.stylesheet()
      .selector('node')
      .css({
          'shape': 'roundrectangle',
          'height': 80,
          'width': 150,
          'background-fit': 'cover',
          'background-color': '#F5F5F5',
          'border-color': '#F5F5F5',
          'border-width': 3,
          'border-opacity': 0.5,
          'text-valign': 'center',
          'content': 'data(name)',
       })
       .selector('edge')
       .css({
           'width': 6,
           'target-arrow-shape': 'triangle',
           'line-color': '#0088cc',
           'target-arrow-color': '#0088cc'
       }),
   elements: data,
   zoomingEnabled: false,
   layout: {
       name: 'breadthfirst',
       directed: true,
       padding: 10
   }
}); // cy init

After we have initialized the diagram, we have to set the size of our container div to be at least as high as the bounds of the graph. We also need to reset the size anytime someone resizes the window.

cy.on('ready', function () {
    updateBounds();
});
//if they resize the window, resize the diagram
$(window).resize(function () {
    updateBounds();
});

var updateBounds = function () {
    var bounds = cy.elements().boundingBox();
    $('#cyContainer').css('height', bounds.h + 300);
    cy.center();
    cy.resize();
    //fix the Edgehandles
    $('#cy').cytoscapeEdgehandles('resize');
};

I am also calling updateBounds() any time the user add a node to the graph. This gives me a graph that is full size and grows vertically. I can scroll down the page just fine as well!

Andrew Serff
  • 2,117
  • 4
  • 21
  • 32
  • I started making this jsbin, but interestingly, it's not working there. Like the resize isn't working...if anyone can see why, let me know and I'll update the answer with a working example: http://jsbin.com/dacanayima/1/edit?html,js,output – Andrew Serff Dec 12 '14 at 18:21
  • What is the context of `#cyContainer` here? Shouldn't you be changing the height of `#cy` element instead? – Lloyd Banks Apr 05 '17 at 15:37
  • If I remember right (it was like 2 years ago...) the cy element has a height of 100%, so changing the height of the cyContainer allows the cy element to just grow into the new space. I don't remember if I tried without the cyContainer...you can see the code in that jsbin though. – Andrew Serff Apr 14 '17 at 22:13
2

(1) Layouts usually fit to the graph. Set layoutOptions.fit: false to override this default behaviour (at least for included layouts).

(2) The use of (1) means that running the layout will leave the graph viewport in the reset state (i.e. default zoom of 1 at origin position { x: 0, y: 0 }). If you want the viewport maintained at zoom: 1 but with an altered pan position, you can use cy.pan() with some simple calculations with cy.elements().boundingBox(). You may also find cy.center() useful -- though perhaps only horizontally in your case.

(3) The use of (2) means that your graph viewport (i.e. canvas) will be the same size, but the user will be able to pan down to see the remainder of the graph. If you prefer scrolling over panning, you will need to implement your own mechanism for this. You can make clever combination of cy.elements().boundingBox() and jQuery('#cy-div').css(), for example, to adjust the cy div to the size of the graph. You may want to turn off user panning and zooming (and autolock nodes etc.), if the graph is not interactive.

maxkfranz
  • 11,896
  • 1
  • 27
  • 36
  • Thanks Max, a couple of questions: 1) Is there a way to make cytoscape ignore the scroll event? Right now, if the page is long and I try to scroll while over the cytoscape, it doesn't scroll. I have to scroll off the graph. 2) using #3, can I change the size of the div after cytoscape has been initialized? Do I just call cy.resize() at that point? – Andrew Serff Dec 11 '14 at 20:05
  • Hey there, it's been a while but you seem very active here so, I'm struggling on (2) as I'm new to the library. How can I do that? Padding/zooming is fine for me, I just want to limit the amount of nodes aligned horizontally. Thanks – CaldeiraG Oct 03 '19 at 07:29
1

Well, I think you could set the zoom amount to fixed and disable zoom in/out, and use some strategy to dynamically change your div/page's height.

This answer or this one should help you.

Community
  • 1
  • 1
gcpdev
  • 442
  • 6
  • 20
  • The first link is about embedded `iframe`, second link assumes `jQuery`. Although both are somehow related to scaling the OP's problem is probably solvable by means of the [Cytoscape's Viewport manipulation API](http://js.cytoscape.org/#core/viewport-manipulation) – xmojmr Dec 11 '14 at 16:53
  • I'm starting to try out dynamically determining the height of the page based on the nodes I have. Will update when I have tried some things out. – Andrew Serff Dec 11 '14 at 18:15