Last active
July 22, 2018 09:47
-
-
Save artyomtrityak/262ddbadc3492808b15b0202ef744c0c to your computer and use it in GitHub Desktop.
React HOC for D3js to pass width / height to React
This file contains hidden or 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 ReactDOM from "react-dom"; | |
import React from "react"; | |
import _ from "lodash"; | |
// -------------------------------- | |
// With width / hegit HOC for D3.js | |
// -------------------------------- | |
const WithSize = Child => | |
class extends React.Component { | |
state = { | |
width: null, | |
height: null | |
}; | |
constructor(props) { | |
super(props); | |
this.setSize = this.setSize.bind(this); | |
this.setSizeDebounced = _.debounce(this.setSize, 1000); | |
window.addEventListener("resize", this.setSizeDebounced); | |
} | |
componentDidMount() { | |
this.setSize(); | |
} | |
componentWillUnmount() { | |
window.removeEventListener("resize", this.setSizeDebounced); | |
} | |
setSize() { | |
const width = ReactDOM.findDOMNode(this).clientWidth; | |
const height = ReactDOM.findDOMNode(this).clientHeight; | |
this.setState({ width, height }); | |
} | |
render() { | |
const { width, height } = this.state; | |
return ( | |
<div style={{ width: "100%", height: "100%" }}> | |
{width && height ? <Child width={width} height={height} {...this.props} /> : null} | |
</div> | |
); | |
} | |
}; | |
// -------------------------------- | |
// Usage | |
// -------------------------------- | |
import React from "react"; | |
import * as d3 from "d3"; | |
import WithSize from "../../shared/with-size"; | |
class Chart1 extends React.Component { | |
static displayName = "D3Chart"; | |
state = { | |
data: [...], | |
scaleX: null, | |
scaleY: null | |
}; | |
componentDidMount() { | |
this.setState({ | |
scaleX: this.createScaleX(), | |
scaleY: this.createScaleY() | |
}); | |
} | |
compomentDidUpdate(prevProps) { | |
// width / height props from WithSize HOC | |
if (prevProps.width !== this.props.width || prevProps.height !== this.props.height) { | |
this.setState({ | |
scaleX: this.createScaleX(), | |
scaleY: this.createScaleY() | |
}); | |
} | |
} | |
createScaleX() { | |
return d3 | |
.scaleLinear() | |
.domain([0, d3.max(this.state.data)]) | |
// width / height props from WithSize HOC | |
.range([0, this.props.width]); | |
} | |
createScaleY() { | |
return d3 | |
.scaleBand() | |
.domain(this.state.data) | |
// width / height props from WithSize HOC | |
.range([0, this.props.height]) | |
.padding(0.1); | |
} | |
render() { | |
// Render bars, rect etc, use this.state scales | |
} | |
} | |
export default WithSize(HorisontalBarChart1); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment