-
-
Save borm/f064749b28e1bb651faf27d48acfb00a to your computer and use it in GitHub Desktop.
react d3 (v4.0) stacked bar chart using rd3
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
'use strict'; | |
import { scaleOrdinal, schemeCategory20c } from 'd3-scale'; | |
import React from 'react'; | |
module.exports = React.createClass({ | |
displayName: 'BarChart', | |
propTypes: { | |
colors: React.PropTypes.func, | |
data: React.PropTypes.array.isRequired, | |
xScale: React.PropTypes.func.isRequired, | |
xAccessor: React.PropTypes.func, | |
yScale: React.PropTypes.func.isRequired, | |
svgComponent: React.PropTypes.any, | |
transform: React.PropTypes.string, | |
}, | |
getDefaultProps() { | |
return { | |
colors: scaleOrdinal(schemeCategory20c), | |
xAccessor: d => d.x, | |
SvgComponent: (props) => <rect {...props} />, | |
transform: 'translate(0 ,0)', | |
}; | |
}, | |
_renderSeries(stackedData) { | |
return stackedData.map(item => { | |
const { key, index } = item | |
const data = Array.from(item) | |
return data.map(d => { | |
return this._renderItem(d, key, index) | |
}) | |
}); | |
}, | |
_renderItem(item, key, index) { | |
const { colors, xScale, yScale, SvgComponent, xAccessor } = this.props; | |
const x = xScale(xAccessor(item['data'])) | |
const y = yScale(item[1]); | |
const height = yScale(item[0]) - yScale(item[1]); | |
const width = xScale.rangeBand() | |
return ( | |
<SvgComponent | |
x={x} | |
y={y} | |
height={height} | |
width={width} | |
fill={colors(index)} | |
item={item} | |
item-key={key} | |
item-index={index} | |
/> | |
); | |
}, | |
render() { | |
const props = this.props; | |
return ( | |
<g transform={props.transform}> | |
{this._renderSeries(props.data)} | |
</g> | |
); | |
}, | |
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Component } from 'react' | |
import { BarChart } from '../src/barchart' | |
import { stack } from 'd3-shape' | |
import SvgContainer from '../src/common/charts/SvgContainer'; | |
import { XAxis, YAxis } from '../src/common'; | |
var barData = [ | |
{month: new Date(2015, 0, 1), apples: 3840, bananas: 1920, cherries: 960, dates: 400}, | |
{month: new Date(2015, 1, 1), apples: 1600, bananas: 1440, cherries: 960, dates: 400}, | |
{month: new Date(2015, 2, 1), apples: 640, bananas: 960, cherries: 640, dates: 400}, | |
{month: new Date(2015, 3, 1), apples: 320, bananas: 480, cherries: 640, dates: 400} | |
]; | |
const width = 500; | |
const height = 200; | |
// stacked | |
const stacked = stack() | |
.keys(['apples', 'bananas', 'cherries', 'dates']) | |
const stackedData = stacked(barData) | |
// xScale | |
const xDomain = barData.map(d => d.month) | |
const xScale = d3.scale.ordinal() | |
.domain(xDomain) | |
.rangeRoundBands([0, width], 0.25); | |
const xAccessor = d => d['month'] | |
// yScale | |
// in stacked bar chart, the maximum height we need for | |
// yScale domain is the sum of y0 + y | |
const maxYDomain = d3.max(stackedData, (d) => ( | |
d3.max(d, (d2) => ( | |
// where y0, y is generated by d3.layout.stack() | |
d2[0] + d2[1] | |
)) | |
)); | |
const yDomain = [0, maxYDomain]; | |
const yScale = d3.scale.linear().range([height, 0]).domain(yDomain); | |
let isMouseOver = false | |
class Rect extends Component { | |
getInitialState() { | |
return { | |
fill: this.props.fill | |
} | |
} | |
render() { | |
console.log(this.props) | |
console.log(this.state) | |
return ( | |
<rect | |
{...this.props} | |
fill={this.state.fill} | |
/> | |
) | |
} | |
} | |
export default class MyBarChart extends Component { | |
render() { | |
return ( | |
<SvgContainer width={width}> | |
<BarChart | |
data={stackedData} | |
width={width} | |
height={height} | |
xScale={xScale} | |
yScale={yScale} | |
xAccessor={xAccessor} | |
transform={'translate(50, 0)'} | |
SvgComponent={Rect} | |
/> | |
<XAxis | |
width={width} | |
height={height} | |
xScale={xScale} | |
tickFormatting={d => d.getMonth() + 1 } | |
transform={'translate(50, 200)'} | |
/> | |
<YAxis | |
width={width} | |
height={height} | |
yScale={yScale} | |
transform={'translate(50, 0)'} | |
/> | |
</SvgContainer> | |
) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment