Show Buttons
Share On Facebook
Share On Twitter
Share On Google Plus
Share On Linkdin
Share On Reddit
Share On Stumbleupon
Contact us
Hide Buttons

Render a d3js Tree as a React Component

React is very good and opti­miz­ing client side ren­der. How­ever, what if you need to use d3 in your project? For sim­ple dia­grams such as bar graphs etc, you can mess around with svg prop­er­ties and let react han­dle the ren­der for you. But what if you just need to use the expres­sive power of d3 but still retain the com­po­nent model of React.

For­tu­nately, there is a still a way to make these two pow­er­ful frame­works play together. The way we are going to do that is by encap­su­lat­ing a func­tion that ren­ders a tree within a React com­po­nent. The com­po­nent itself only ren­ders a blank svg node in the ren­der func­tion. But inside of the com­po­nent­Did­Mount func­tion, we invoke the d3 func­tion that draws our data on the blank svg.

NOTE: The entire source code of this project is avail­able at github on the react-d3-tree branch of our react-webpack-setup project. If you are inclined to learn how to setup react with web­pack you can check­out another arti­cle that cov­ers the topic in detail.


Since we are going to use the react-webpack-setup project, we will be con­ve­niently using npm and require in our front end code.


The pack­ages

D3 is avail­able as a pack­age from npm, so you can add it to your project by running

npm install d3

The com­po­nents

The next part of the code shows the main Page.jsx file that acts as the mas­ter com­po­nent of the page. Since this is just an exam­ple, we will be cre­at­ing the tree­Data object in this com­po­nent and pass­ing it down to the D3Tree component.

js/components/index/Page.jsx

/**
 * @jsx React.DOM
 */

var React = require('react'),
    D3Tree = require('./D3Tree'),
    treeData = [
      {
        "name": "Top Level",
        "parent": "null",
        "children": [
          {
            "name": "Level 2: A",
            "parent": "Top Level",
            "children": [
              {
                "name": "Son of A",
                "parent": "Level 2: A"
              },
              {
                "name": "Daughter of A",
                "parent": "Level 2: A"
              }
            ]
          },
          {
            "name": "Level 2: B",
            "parent": "Top Level"
          }
        ]
      }
    ];

var Page = React.createClass({

    render: function() {

        return (
            <div>
                <D3Tree treeData={treeData} />
            </div>
        );

    }

});

module.exports = Page;

To actu­ally ren­der the tree, we will be wrap the code in Mike Bostock’s exam­ple in a func­tion ren­derTree but only change one line in that code and replace it with our own selec­tor for the svg node which is passed in as the argument.

js/components/index/D3Tree.jsx

/**
 * @jsx React.DOM
 */

var React = require('react'),
  d3 = require('d3');

var D3Tree = React.createClass({

  componentDidMount: function(){
    var mountNode = this.getDOMNode();

    // Render the tree usng d3 after first component mount
    renderTree(this.props.treeData, mountNode);
  },

  shouldComponentUpdate: function(nextProps, nextState){
    // Delegate rendering the tree to a d3 function on prop change
    renderTree(this.props.treeData, this.getDOMNode());

    // Do not allow react to render the component on prop change
    return false;
  },

  render: function() {

    // Render a blank svg node
    return (
      <svg></svg>
    );
  }

});


var renderTree = function(treeData, svgDomNode) {
    // Add the javascript code that renders the tree from
    // http://bl.ocks.org/d3noob/8329404
    // And replace the line that reads
    // var svg = d3.select("body").append("svg")
    // with 
    // var svg = d3.select(svgDomNode)
}

That said, you are now ready for show­time. To see the work­ing exam­ple for your­self, down­load the branch — react-backbone-model from our repos­i­tory and run the fol­low­ing com­mands on your terminal.

sudo npm install -g grunt-cli
npm install
npm run dev

Then open localhost:3000/index.html in your browser and you should be able to see a tree ren­dered using d3 and react.



Ryan Sukale

Ryan is just a regular guy next door trying to manage his life and finances.