Cytoscape and ReactJS integration
Asked Answered
U

4

16

I am trying to use use Cytoscape with ReactJS and some how nothing is getting displayed in the simple component i am trying.

Here is the code. I am returning an empty object in mapStateToProps as i am trying to display a static graph where i have hard coded the edges and nodes.

Cytoscape version i am using is from my package.json

"cytoscape": "^2.7.6", "react": "^15.2.1",

Here is the Cyctoscape jsbin i am using for my sample.

enter link description here

Appreciate any help.

Thanks

import React,{Component} from 'react';
import cytoscape from 'cytoscape';

import {connect} from 'react-redux';
import { bindActionCreators } from 'redux';

class GraphContainer extends React.Component{
    constructor(props){
        super(props);
        this.renderCytoscapeElement = this.renderCytoscapeElement.bind(this);
    }

    renderCytoscapeElement(){

        console.log('* Cytoscape.js is rendering the graph..');

        this.cy = cytoscape(
        {
            container: document.getElementById('cy'),

            boxSelectionEnabled: false,
            autounselectify: true,

            style: cytoscape.stylesheet()
                .selector('node')
                .css({
                    'height': 80,
                    'width': 80,
                    'background-fit': 'cover',
                    'border-color': '#000',
                    'border-width': 3,
                    'border-opacity': 0.5,
                    'content': 'data(name)',
                    'text-valign': 'center',
                })
                .selector('edge')
                .css({
                    'width': 6,
                    'target-arrow-shape': 'triangle',
                    'line-color': '#ffaaaa',
                    'target-arrow-color': '#ffaaaa',
                    'curve-style': 'bezier'
                })
                ,
            elements: {
                nodes: [
                    { data: { id: 'cat' } },
                    { data: { id: 'bird' } },
                    { data: { id: 'ladybug' } },
                    { data: { id: 'aphid' } },
                    { data: { id: 'rose' } },
                    { data: { id: 'grasshopper' } },
                    { data: { id: 'plant' } },
                    { data: { id: 'wheat' } }
                ],
                edges: [
                    { data: { source: 'cat', target: 'bird' } },
                    { data: { source: 'bird', target: 'ladybug' } },
                    { data: { source: 'bird', target: 'grasshopper' } },
                    { data: { source: 'grasshopper', target: 'plant' } },
                    { data: { source: 'grasshopper', target: 'wheat' } },
                    { data: { source: 'ladybug', target: 'aphid' } },
                    { data: { source: 'aphid', target: 'rose' } }
                ]
            },

            layout: {
                name: 'breadthfirst',
                directed: true,
                padding: 10
            }
            }); 
    }

    componentDidMount(){
        this.renderCytoscapeElement();
    }

    render(){
        return(
            <div className="node_selected">
                <div style="{height:'400px';width:'400px'}" id="cy"/>
            </div>
        )
    }
}

function mapStateToProps(state){
    return {};
}


export default connect(mapStateToProps,null)(GraphContainer);
Unction answered 28/7, 2016 at 2:26 Comment(4)
this should work. anything on the console? if there is no default exports on cytoscape, import { cytoscape }.Infidel
No errors in the console. i am seeing the console.log from renderCytoscapeElement() so i guess there is nothing wrong with the import. when i replaced my import with the one you suggested i got an error GraphContainer.js?faef:24Uncaught TypeError: Cannot read property 'stylesheet' of undefinedUnction
Since this question was posted, a well crafted react cytoscape.js component has been made available: github.com/plotly/react-cytoscapejsDiagnostic
I think the style attribute of the container div should be written like so : <div style={{height:'400px';width:'400px'}} id="cy"/>Fourteenth
A
13

For those still looking for how to get the code posted working - I was able to get it working by modifying the cy div, specifying its style with non-zero height and width.

render() {
  let cyStyle = {
    height: '1000px',
    width: '1000px',
    margin: '20px 0px'
  };

  return (
    <div>
      <div style={cyStyle} id="cy"/>
    </div>
  );
}
Amontillado answered 12/1, 2017 at 1:17 Comment(1)
The problem in the OP code is in the line : <div style="{height:'400px';width:'400px'}" id="cy"/>. The style attribute should be written like so : style={{height:'400px';width:'400px'}}. No additional variable needed like yours, because it is identical.Fourteenth
E
4

I had to integrate cytoscape.js with react as well, but no redux, so wrote a gist in case anybody else needs it.

code example

Emmery answered 7/8, 2017 at 17:7 Comment(0)
V
3

For a basic version of the above using the cytoscape "Getting Started" example and using React hooks you can do this:

import React, {Fragment, useEffect, useRef} from 'react';
import cytoscape from 'cytoscape'

const GraphTest = () => {

 const graphRef = useRef(null)

 const drawGraph = () => {
 const cy = cytoscape({
  container: graphRef.current,
  elements: [
    { data: { id: 'a' } },
    { data: { id: 'b' } },
    {
      data: {
        id: 'ab',
        source: 'a',
        target: 'b'
      }
    }]
  })
 }

 useEffect(() => {
  drawGraph()
 }, [])

 return (
  <Fragment>
   <h2>Graph Test</h2>
   <div ref={graphRef} style={{width: '100%', height: '80vh'}}>
   </div>
  </Fragment>
 )
}

export default GraphTest
Vesica answered 16/4, 2022 at 15:35 Comment(0)
U
2

I am able to resolve the Issue. I missed the Styles for the Layer itself and hence it is defaulting to 0px height and 0px width.

Thanks

Unction answered 28/7, 2016 at 15:27 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.