4

I'm trying to use the graphing library MetricsGraphs.js with React.js. Like many graphing libraries, MetricsGraphics works by directly mutating the DOM. Unfortunately, this doesn't play very well with ReactJS. I've tried a bunch of different strategies, but I don't seem to be able to get past the fact that MetricsGraphs.js needs direct access to a DOM element that it can mutate. Have I overlooked anything, or is there no way to use MetricsGraphics.js with React without serious modifications to the library?

haroba
  • 2,120
  • 4
  • 22
  • 37
  • Look into getDOMNode(), which will allow you to access dom elements once the component already mounted. https://facebook.github.io/react/docs/component-api.html#getdomnode – easwee Jul 07 '15 at 13:47
  • @Aqwis did you resolve this? – Ben Dec 24 '15 at 00:55
  • @Ben I recall resolving this through some ugly hacking in the end, but I unfortunately cannot recall exactly how as it's been several months since I last looked at the problem. – haroba Jan 02 '16 at 17:26

2 Answers2

2

You can use ref property of the component to get access to its DOM elements in React.

These refs (references) are especially useful when you need to: find the DOM markup rendered by a component (for instance, to position it absolutely), use React components in a larger non-React application, or transition your existing codebase to React.

You can read more about refs in React refs documentation

Here is an example which works in my projects today.

import React, { Component } from 'react';

import MG from 'metrics-graphics';
import './node_modules/metrics-graphics/dist/metricsgraphics.css'; // path to the CSS of metricsgraphics

class Graph extends Component {
  componentDidMount() {
    MG.data_graphic({
      title: "Line Chart",
      description: "This is a simple line chart.",
      data: data,
      width: 600,
      height: 200,
      right: 40,
      target: this.target,
      x_accessor: 'date',
      y_accessor: 'value'
    });
  }

  render() {
    return <div ref={(ref) => this.target = ref}></div>;
  }
}

export default Graph;

update Had to update ref to be a callback instead of a string to keep things simpler and to keep it working in the future due to few notes in the documentation:

A note from Cautions section

If you want to preserve Google Closure Compiler Crushing resilience, make sure to never access as a property what was specified as a string. This means you must access using this.refs['myRefString'] if your ref was defined as ref="myRefString".

A note from the ref String Attribute section

Although string refs are not deprecated, they are considered legacy, and will likely be deprecated at some point in the future. Callback refs are preferred.

anvk
  • 1,183
  • 8
  • 10
1

Note that string refs are deprecated so you should use

class Graph extends Component {
  componentDidMount() {

    MG.data_graphic({
      title: "Line Chart",
      description: "This is a simple line chart.",
      data: data,
      width: 600,
      height: 200,
      right: 40,
      target: this.elem,
      x_accessor: 'date',
      y_accessor: 'value'
    });
  }

  render() {
    return <div ref={el => {if (el){this.elem = el}}}></div>;
  }
}

export default Graph;
johans
  • 1,674
  • 12
  • 7