Skip to content

Instantly share code, notes, and snippets.

@tibotiber
Last active March 10, 2018 12:24
Show Gist options
  • Save tibotiber/89ac7a2aefccca9e548986155b5ccfca to your computer and use it in GitHub Desktop.
Save tibotiber/89ac7a2aefccca9e548986155b5ccfca to your computer and use it in GitHub Desktop.
RD3 medium post content
class Chart extends React.Component {
// ...
componentDidUpdate (prevProps, prevState) {
const stripState = p => _.omit(p, ['hover'])
if (!shallowEqual(stripState(this.state), stripState(prevState))) {
this.renderD3()
}
}
// ...
setHover (hX) {
this.setState({
hover: hX
})
}
// ...
computeTooltipProps (hX) {
const hoveredData = _.map(this.props.data, 'values').map(d =>
_.find(d, {x: hX})
)
return {
style: {
top: this.y(_.sum(_.map(hoveredData, 'y'))),
left: this.x(hX)
},
content: `${hX}: ${_.map(hoveredData, 'y').join(', ')}`
}
}
// ...
render () {
return (
<div>
{this.state.chart}
{this.state.hover &&
<Tooltip {...this.computeTooltipProps(this.state.hover)} />
}
</div>
)
}
// ...
renderD3() {
// ...
// make x and y helpers available to JSX for tooltips positioning
const x = d3.scale
.ordinal()
.domain(this.props.xDomain)
.rangeRoundBands([0, width], 0.08)
this.x = x
const y = d3.scale.linear().domain([0, yStackMax]).range([height, 0])
this.y = y
// ...
// add mouse event listeners
let rect = layer.selectAll('rect').data(d => d.values)
rect
.enter()
.append('rect')
.attr('x', d => x(d.x))
.attr('y', height)
.attr('width', x.rangeBand())
.attr('height', 0)
.on('mouseover', d => {
clearTimeout(this.unsetHoverTimeout)
this.setHover(d.x)
})
.on('mouseout', d => {
this.unsetHoverTimeout = setTimeout(
() => this.setHover(null),
200
)
})
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment