Created
August 1, 2018 07:20
-
-
Save alieslamifard/62dcc50e8a387bd5a83c7c359b0f4e3a to your computer and use it in GitHub Desktop.
sample component for d3js with react-faux-dom
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 React from 'react'; | |
import PropTypes from 'prop-types'; | |
import withStyles from 'isomorphic-style-loader/lib/withStyles'; | |
import cs from 'classnames'; | |
import * as d3 from 'd3'; | |
import ReactFauxDOM from 'react-faux-dom'; | |
import s from './D3C.scss'; | |
class D3C extends React.Component { | |
static propTypes = { | |
className: PropTypes.string, | |
data: PropTypes.object, | |
width: PropTypes.number.isRequired, | |
height: PropTypes.number.isRequired, | |
}; | |
static defaultProps = { | |
className: null, | |
data: null, | |
}; | |
constructor(props) { | |
super(props); | |
this.state = {}; | |
} | |
drawChart = () => { | |
// eslint-disable-next-line new-cap | |
const elm = new ReactFauxDOM.createElement('svg'); | |
elm.setAttribute('width', this.props.width); | |
elm.setAttribute('height', this.props.height); | |
const svg = d3.select(elm); | |
const margin = { top: 20, right: 20, bottom: 30, left: 50 }; | |
const width = +svg.attr('width') - margin.left - margin.right; | |
const height = +svg.attr('height') - margin.top - margin.bottom; | |
const x = d3 | |
.scaleBand() | |
.rangeRound([0, width]) | |
.padding(0.1); | |
const y = d3.scaleLinear().rangeRound([height, 0]); | |
const g = svg | |
.append('g') | |
.attr('transform', `translate(${margin.left},${margin.top})`); | |
x.domain(this.props.data.map(d => d.letter)); | |
y.domain([0, d3.max(this.props.data, d => d.frequency)]); | |
g | |
.append('g') | |
.attr('class', 'axis axis--x') | |
.attr('transform', `translate(0,${height})`) | |
.call(d3.axisBottom(x)); | |
g | |
.append('g') | |
.attr('class', 'axis axis--y') | |
.call(d3.axisLeft(y).ticks(10, '%')) | |
.append('text') | |
.attr('transform', 'rotate(-90)') | |
.attr('y', 6) | |
.attr('dy', '0.71em') | |
.attr('text-anchor', 'end') | |
.text('Frequency'); | |
g | |
.selectAll('.bar') | |
.data(this.props.data) | |
.enter() | |
.append('rect') | |
.attr('class', 'bar') | |
.attr('x', d => x(d.letter)) | |
.attr('y', d => y(d.frequency)) | |
.attr('width', x.bandwidth()) | |
.attr('height', d => height - y(d.frequency)); | |
return elm.toReact(); | |
}; | |
render() { | |
const { className } = this.props; | |
return ( | |
<div className={cs('D3C', s.root, className)}>{this.drawChart()}</div> | |
); | |
} | |
} | |
export default withStyles(s)(D3C); | |
export const D3CTest = D3C; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment