Chart doesn't display on using "position:relative" in the div in Cystoscape.js

I wish to confine the chart to a 'bordered' div. If I replace the position:absolute to position:relative for the container div, the graph doesn't render/display at all.

If anyone could shed some light?

  <script src="http://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script src="http://cytoscape.github.io/cytoscape.js/api/cytoscape.js-latest/cytoscape.min.js"></script>
<script>
$(function(){ // on dom ready

$('#cy').cytoscape({
  layout: {
    name: 'cose',
    padding: 10,
    randomize: true
 },

style: cytoscape.stylesheet()
.selector('node')
  .css({
    'shape': 'data(faveShape)',
    'width': 'mapData(weight, 40, 80, 20, 60)',
    'content': 'data(name)',
    'text-valign': 'center',
    'text-outline-width': 2,
    'text-outline-color': 'data(faveColor)',
    'background-color': 'data(faveColor)',
    'color': '#fff'
  })
.selector(':selected')
  .css({
    'border-width': 3,
    'border-color': '#333'
  })
.selector('edge')
  .css({
    'curve-style': 'bezier',
    'opacity': 0.666,
    'width': 'mapData(strength, 70, 100, 2, 6)',
    'target-arrow-shape': 'triangle',
    'source-arrow-shape': 'circle',
    'line-color': 'data(faveColor)',
    'source-arrow-color': 'data(faveColor)',
    'target-arrow-color': 'data(faveColor)'
  })
.selector('edge.questionable')
  .css({
    'line-style': 'dotted',
    'target-arrow-shape': 'diamond'
  })
.selector('.faded')
  .css({
    'opacity': 0.25,
    'text-opacity': 0
  }),

elements: {
nodes: [
  { data: { id: 'j', name: 'Jerry', weight: 65, faveColor: '#6FB1FC', faveShape: 'triangle' } },
  { data: { id: 'e', name: 'Elaine', weight: 45, faveColor: '#EDA1ED', faveShape: 'ellipse' } },
  { data: { id: 'k', name: 'Kramer', weight: 75, faveColor: '#86B342', faveShape: 'octagon' } },
  { data: { id: 'g', name: 'George', weight: 70, faveColor: '#F5A45D', faveShape: 'rectangle' } }
],
edges: [
  { data: { source: 'j', target: 'e', faveColor: '#6FB1FC', strength: 90 } },
  { data: { source: 'j', target: 'k', faveColor: '#6FB1FC', strength: 70 } },
  { data: { source: 'j', target: 'g', faveColor: '#6FB1FC', strength: 80 } },

  { data: { source: 'e', target: 'j', faveColor: '#EDA1ED', strength: 95 } },
  { data: { source: 'e', target: 'k', faveColor: '#EDA1ED', strength: 60 }, classes: 'questionable' },

  { data: { source: 'k', target: 'j', faveColor: '#86B342', strength: 100 } },
  { data: { source: 'k', target: 'e', faveColor: '#86B342', strength: 100 } },
  { data: { source: 'k', target: 'g', faveColor: '#86B342', strength: 100 } },

  { data: { source: 'g', target: 'j', faveColor: '#F5A45D', strength: 90 } }
]
},
ready: function(){
window.cy = this;

// giddy up
}
});

}); // on dom ready
</script>

<style>
body { 
font: 14px helvetica neue, helvetica, arial, sans-serif;
}

#cy {
  height: 100%;
  width: 100%;
  position: absolute;
  left: 0;
  top: 0;
}
</style>  
<body>
  <div id="cy"></div>
</body>

I wish to confine the graph in the cy div with a border around the div.

Following are the things I have attempted:

  1. Nested divs
  2. Relative positioning of cy as well as parent divs (when nested divs were used).
  3. Even tried confining in bootstrap grids
  4. Used the latest Cytoscape.js
  5. Even tried changing/playing with absolute positioning tags with in the library.

I didn't think it would be complicated at all, but somehow I am not able to crack it.

I have referred previous questions at: http://cytoscape-cvs.narkive.com/1O4DLa9g/cytoscape-cytoscape-js-e85d5c-use-position-relative-on-canvas-parent-containe https://github.com/cytoscape/cytoscape.js/commit/e85d5cad1ca87839f075622f642903828cf6f78e

Upvotes: 3

Views: 1842

Answers (3)

Victoria Stuart
Victoria Stuart

Reputation: 5072

A rather annoying issue: difficulty in placing additional <div> elements around the Cytoscape.js <div id='cy'></div> element.

Without investigating further, it appears that the Cytoscape.js code auto-formats that div (z-index?), alluded to here,

https://github.com/cytoscape/cytoscape.js/issues/402

and / or other aspects of the DOM (search for "DOM" here: https://js.cytoscape.org).

The accepted answer provided the solution; here is how I employed it.

<!DOCTYPE html>
<head>
  <!--
    Notes:
      1. I couldn't use % with #cy; use rem, or viewport { vh | vw } units.
      2. I can now place <div> elements above / below the #cy div.
  -->
  <style>
    #cy {
      width: 40vw;
      height: 40vh;
      // position: relative;
      border: 1px solid #949494;
      overflow: hidden;
    }
    #cyWrapper {
      // ...
    }
    #controls {
      // ...
    }
  </style>

  <script src='https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.18.2/cytoscape.min.js'></script>
</head>

<body>
  <div><p>apple</p></div>

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

  <script>
  fetch('ontology2.cyjs').then(res => res.json())
    .then(d => {
        setup(d);
    })
    .catch(function(error) {
        console.log('Error: failed promise')
        if (error) throw error;
    });

  function setup(myData) {
    var cy = cytoscape({
      container: document.getElementById('cy'),
      // [ ... snip ... ]
  };
  </script>

  <div id=#controls>
    <p>banana</p>
  </div>
</body>
</html>

cytoscape.js div positioning

"apple", the Cytoscape.js graph, and "carrot" each reside in separate <div-elements.

References

Upvotes: 1

maxkfranz
maxkfranz

Reputation: 12242

If you use position: relative and specify dimensions relatively, they're relative to the containing block, body.

But body has no well defined height. Because the default user agent stylesheet probably has body { display: block; }, body will be the width of its parent -- the document.

However, height is undefined for body in the default stylesheet, so like any block element it takes on the height of the sum of its child elements. But one of the child elements, #cy is defined in terms of the height of its parent. We have a cyclic dependency, so the percentage height specified for #cy can not be used. So it ends up with zero height, the default height for an empty block element.

Make sure to specify the size of your Cytoscape div so it's nonzero, and it should work just fine. Try using viewport units like height: 100vh; width: 100vw; or set body { height: 100%; width: 100% } so percent values make sense on #cy.

Refer to the MDN for details: https://developer.mozilla.org/en-US/docs/Web/CSS/height

Upvotes: 2

desc
desc

Reputation: 1210

I ran into what I believe is a similar issue. I added a wrapper div to generate a border around a position: relative cy div:

<div id="cyWrapper" style="position: relative; border: 2px solid #212523">

    <div id='cy'></div>

</div>

Upvotes: 3

Related Questions