manniru
1/7/2014 - 9:17 PM

React + D3

React + D3

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>React + D3</title>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">    
    <script src="http://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.5.2/underscore.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/react/0.8.0/react.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/react/0.8.0/JSXTransformer.js"></script>
    <script src="http://cdnjs.cloudflare.com/ajax/libs/d3/3.3.13/d3.js"></script>
  </head>
  <body>
    <div id="container"> </div>
    
    <script type="text/jsx">    
      /** @jsx React.DOM */
      var Chart = React.createClass({
        render: function() {
          return (
            <svg width={this.props.width} height={this.props.height}>{this.props.children}</svg>
          );
        }
      });

      var Bar = React.createClass({
        getDefaultProps: function() {
          return {
            width: 0,
            height: 0,
            offset: 0
          }
        },

        render: function() {
          return (
            <rect fill={this.props.color}
              width={this.props.width} height={this.props.height} 
              x={this.props.offset} y={this.props.availableHeight - this.props.height} />
          );
        }
      });

      var DataSeries = React.createClass({
        getDefaultProps: function() {
          return {
            title: '',
            data: []
          }
        },

        render: function() {
          var props = this.props;

          var yScale = d3.scale.linear()
            .domain([0, d3.max(this.props.data)])
            .range([0, this.props.height]);

          var xScale = d3.scale.ordinal()
            .domain(d3.range(this.props.data.length))
            .rangeRoundBands([0, this.props.width], 0.05);

          var bars = _.map(this.props.data, function(point, i) {
            return (
              <Bar height={yScale(point)} width={xScale.rangeBand()} offset={xScale(i)} availableHeight={props.height} color={props.color} key={i} />
            )
          });

          return (
            <g>{bars}</g>
          );
        }
      });
    
      var BarChart = React.createClass({
        getDefaultProps: function() {
          return {
            width: 600,
            height: 300
          }
        },

        render: function() {
          return (
            <Chart width={this.props.width} height={this.props.height}>
              <DataSeries data={[ 30, 10, 5, 8, 15, 10 ]} width={this.props.width} height={this.props.height} color="cornflowerblue" />
            </Chart>
          );
        }
      });

      React.renderComponent(
        <BarChart />,
        document.getElementById('container')
      );
    </script>
  </body>
</html>