React With D3 - Plunker

<!DOCTYPE html>
<html>
 <head>
 <link data-require="bootstrap@3.3.2" data-semver="3.3.2" rel="stylesheet" href="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/css/bootstrap.min.css" />
 <script data-require="jquery@2.1.3" data-semver="2.1.3" src="http://code.jquery.com/jquery-2.1.3.min.js"></script>
 <script data-require="bootstrap@3.3.2" data-semver="3.3.2" src="//maxcdn.bootstrapcdn.com/bootstrap/3.3.2/js/bootstrap.min.js"></script>
 <script data-require="d3@3.5.3" data-semver="3.5.3" src="//cdnjs.cloudflare.com/ajax/libs/d3/3.5.3/d3.js"></script>
 <script data-require="react-with-addons@0.12.2" data-semver="0.12.2" src="http://fb.me/react-with-addons-0.12.2.js"></script>
 <link rel="stylesheet" href="style.css" />
 </head>
 <body>
 <h1>React With D3 - Bar Chart Example</h1>
 <div id="app"></div>
 <script src="script.js"></script>
 </body>
</html>
var SetIntervalMixin = {
 componentWillMount: function() {
 this.intervals = [];
 },
 setInterval: function() {
 this.intervals.push(setInterval.apply(null, arguments));
 },
 componentWillUnmount: function() {
 this.intervals.map(clearInterval);
 }
};
var Rect = React.createClass({
 mixins: [SetIntervalMixin], 
 getDefaultProps: function() {
 return {
 width: 0,
 height: 0,
 x: 0,
 y: 0
 }
 },
 
 getInitialState: function() {
 return {
 milliseconds: 0,
 height: 0
 };
 },
 
 shouldComponentUpdate: function(nextProps) {
 return this.props.height !== this.state.height;
 },
 
 componentWillMount: function() {
 console.log('will mount');
 },
 
 componentWillReceiveProps: function(nextProps) {
 this.setState({milliseconds: 0, height: this.props.height});
 },
 
 componentDidMount: function() {
 this.setInterval(this.tick, 10);
 },
 
 tick: function(start) {
 this.setState({milliseconds: this.state.milliseconds + 10});
 },
 
 render: function() {
 var easyeasy = d3.ease('back-out');
 var height = this.state.height + (this.props.height - this.state.height) * easyeasy(Math.min(1, this.state.milliseconds/1000));
 var y = this.props.height - height + this.props.y;
 return (
 <rect className="bar"
 height={height} 
 y={y} 
 width={this.props.width}
 x={this.props.x}
 >
 </rect>
 );
 },
});
var Bar = React.createClass({
 getDefaultProps: function() {
 return {
 data: []
 }
 },
 shouldComponentUpdate: function(nextProps) {
 return this.props.data !== nextProps.data;
 },
 render: function() {
 var props = this.props;
 var data = props.data.map(function(d) {
 return d.y;
 });
 var yScale = d3.scale.linear()
 .domain([0, d3.max(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 = data.map(function(point, i) {
 var height = yScale(point),
 y = props.height - height,
 width = xScale.rangeBand(),
 x = xScale(i);
 return (
 <Rect height={height} 
 width={width} 
 x={x} 
 y={y} 
 key={i} />
 )
 });
 return (
 <g>{bars}</g>
 );
 }
}); 
var Chart = React.createClass({
 render: function() {
 return (
 <svg width={this.props.width} 
 height={this.props.height} >
 {this.props.children}
 </svg>
 );
 }
});
var Axis = React.createClass({
 render: function() {
 return <g></g>
 }
});
var all = [
 {x: 'a', y: 20}, 
 {x: 'b', y: 14}, 
 {x: 'c', y: 12}, 
 {x: 'd', y: 19}, 
 {x: 'e', y: 18}, 
 {x: 'f', y: 15}, 
 {x: 'g', y: 10}, 
 {x: 'h', y: 14}
];
var filtered = [
 {x: 'a', y: 9}, 
 {x: 'b', y: 5}, 
 {x: 'c', y: 6}, 
 {x: 'd', y: 12}, 
 {x: 'e', y: 10}, 
 {x: 'f', y: 7}, 
 {x: 'g', y: 4}, 
 {x: 'h', y: 9}
];
 
 
var App = React.createClass({
 getDefaultProps: function() {
 return {
 width: 500,
 height: 500
 }
 },
 
 getInitialState: function() {
 return {
 data: all
 }
 },
 
 showAll: function() {
 this.setState({data : all})
 },
 
 filter: function() {
 this.setState({data: filtered});
 },
 
 render: function() {
 return (
 <div>
 <div className="selection">
 <ul>
 <li onClick={this.showAll}>All</li>
 <li onClick={this.filter}>Filter</li>
 </ul>
 </div>
 <hr/>
 <Chart width={this.props.width} 
 height={this.props.height}>
 <Bar data={this.state.data} 
 width={this.props.width} 
 height={this.props.height} />
 </Chart>
 </div>
 );
 }
});
 
React.render(
 <App /> ,
 document.getElementById('app')
);
 
body {
 font-family: helvetica, arial, sans-serif; 
}
#app {
 margin: 30px;
}
.bar {
 fill: steelblue;
}
.selection ul {
 margin: 0;
 padding: 0;
}
.selection ul li {
 display: inline;
 text-decoration: none;
 margin-left: 10px;
 cursor: pointer;
}
An example using React to render SVG elements.
D3.js is not used for the rendering part.
Blog post coming soon.

AltStyle によって変換されたページ (->オリジナル) /