Skip to content

Instantly share code, notes, and snippets.

@yinghaochan
Last active February 29, 2016 21:10
Show Gist options
  • Save yinghaochan/30dd9bb9e4faca8006d4 to your computer and use it in GitHub Desktop.
Save yinghaochan/30dd9bb9e4faca8006d4 to your computer and use it in GitHub Desktop.
Bar chart in react
<html>
<head>
<meta name="description" content="React Barchart animated">
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.5.1/lodash.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.6/d3.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-with-addons.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/0.14.7/react-dom.js"></script>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>pure react barchart</title>
<style id="jsbin-css">
.chart div {
font: 10px sans-serif;
background-color: steelblue;
text-align: right;
padding: 3px;
margin: 1px;
color: white;
}
.chart.csstrans rect {
transition: width 1s ease-in;
}
.chart rect {
}
.chart text {
fill: white;
font: 10px sans-serif;
text-anchor: end;
}
.chart .addBar-enter rect{
opacity: 0.5;
width: 0px;
}
.chart .addBar-enter.addBar-enter-active rect{
opacity: 1;
transition: width .1s ease-in;
transition: opacity .5s ease-in;
}
</style>
</head>
<body>
<ul>
<li> 100% React without external DOM manupilation </li>
<li> server side render with partial dataset </li>
<li> handles live data easily </li>
<li> lazy load additional data </li>
<li> Animations in css </li>
<li> Responsive </li>
</ul>
<div id="app">
</div>
<script id="jsbin-javascript">
'use strict';
var ReactCSSTransitionGroup = React.addons.CSSTransitionGroup;
var Chart = React.createClass({
displayName: 'Chart',
getInitialState: function getInitialState() {
return {
windowWidth: 320
};
},
handleResize: function handleResize(e) {
this.setState({ windowWidth: window.innerWidth });
},
componentDidMount: function componentDidMount() {
var _this = this;
window.setTimeout(function () {
return _this.handleResize();
}, 100);
window.addEventListener('resize', this.handleResize);
},
componentWillUnmount: function componentWillUnmount() {
window.removeEventListener('resize', this.handleResize);
},
render: function render() {
var data = this.props.data || [];
var width = this.state.windowWidth - 20;
var barHeight = 21;
var x = d3.scale.linear().domain([0, _.max(data)]).range([0, width]);
var colorScale = d3.scale.category20().domain(data);
return React.createElement(
'svg',
{
className: 'chart csstrans',
width: width,
height: barHeight * data.length },
React.createElement(
ReactCSSTransitionGroup,
{
transitionName: 'addBar',
component: 'g',
transitionEnterTimeout: 2000,
transitionLeaveTimeout: 3000
},
data.map(function (n, i) {
return React.createElement(
'g',
{
key: i,
transform: 'translate(0,' + barHeight * i + ')' },
React.createElement('rect', {
fill: colorScale(n),
width: x(n),
height: barHeight - 1
}),
React.createElement(
'text',
{
x: x(n) - 10,
y: '9.5',
dy: '.35em'
},
n
)
);
})
)
);
}
});
var chartData = [35, 15, 4, 20, 9, 3];
var t = 25;
var render = function render(data) {
return ReactDOM.render(React.createElement(Chart, { data: data }), document.getElementById('app'));
};
var intervalID = window.setInterval(function () {
chartData.push(Math.round(Math.random() * t));
t = t < 50 ? t + 3 : t;
render(chartData);
}, 150);
window.setTimeout(function () {
return clearInterval(intervalID);
}, 10000);
render(chartData);
</script>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment