Integrating Rickshaw JS and React JS

1k views Asked by At

I have 2 files, bundle.jsx (contains React components) and app.js (contains JS functions, which includes Rickshaw classes for building graphs)

Within my react modules (bundle.jsx) within a class i render

<div id="chart_container" />

Within my js file i build on this div

var graph = new Rickshaw.Graph.Ajax( {
element: document.querySelector("#chart_container"), ... 
}

The issue is when i load the 2 files, i expect the graph to be created whenever the div component is rendered by React. However this is not the case as my app.js file gets processed before my React component is rendered.

What is the best solution to this problem? Also am i approaching the problem correctly?

I have tried adding a setTimeout on app.js to load the functions after x seconds. This solves the issue and renders the graph, but is not fool-proof as sometimes the React component does not render in x seconds or renders much faster than x seconds.

Any help/suggestions?

2

There are 2 answers

0
Fabian Schultz On BEST ANSWER

You are looking for componentDidMount(). This method is executed after the component has been rendered the first time, and therefore you can be sure that the chart container exists. Here is an example that illustrates this:

class Example extends React.Component {
  componentDidMount() {
    var graph = new Rickshaw.Graph( {
      element: document.querySelector("#chart_container"), 
      width: 300, 
      height: 200, 
      series: [{
        color: 'steelblue',
        data: [ 
          { x: 0, y: 40 }, 
          { x: 1, y: 49 }, 
          { x: 2, y: 38 }, 
          { x: 3, y: 30 }, 
          { x: 4, y: 32 } ]
      }]
    });

    graph.render();
  }

  render() {
    return(
      <div id="chart_container" />
    );
  }
}

ReactDOM.render(<Example/>, document.getElementById('View'));
<!-- React -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react.min.js"></script>
<!-- React DOM -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.8/react-dom.min.js"></script>
<!-- D3 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.4.11/d3.min.js"></script>
<!-- Rickshaw -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/rickshaw/1.6.0/rickshaw.min.js"></script>

<div id="View"></div>

0
jfunk On

If you are using Rickshaw with React Hooks you can ensure the DOM element is loaded first via the useEffect hook.

  useEffect(() => {
    const graph = new Rickshaw.Graph({
      element: document.querySelector('#chart'),
      renderer: 'scatterplot',
      stroke: true,
      series: [
        {
          data: [...someData],
          color: 'steelblue',
        },
      ],
    });

    graph.render();
  }, []);
  // Then in the functional component...
  return (<div id="chart" />);