Skip to content

Instantly share code, notes, and snippets.

@limscoder
Last active November 20, 2017 19:24
Show Gist options
  • Save limscoder/ebdede0b0e87fda3f58b5d1895efc52a to your computer and use it in GitHub Desktop.
Save limscoder/ebdede0b0e87fda3f58b5d1895efc52a to your computer and use it in GitHub Desktop.
Responding to D3 user interactions
// toggles the color of a hexagon and all of it's surrounding hexagons.
function toggleHex(target, hex) {
const firstColIdx = target.row % 2 ? 0 : -1;
const secondColIdx = target.row % 2 ? 1 : 0;
const isNeighbor =
(hex.col === target.col && hex.row === target.row) || // target
(hex.row === target.row - 1 && (hex.col === target.col + firstColIdx || hex.col === target.col + secondColIdx)) || // above row
(hex.row === target.row && (hex.col === target.col - 1 || hex.col === target.col + 1)) || // same row
(hex.row === target.row + 1 && (hex.col === target.col + firstColIdx || hex.col === target.col + secondColIdx)); // below row
if (isNeighbor) {
return { ...hex, active: !hex.active };
}
return hex;
}
export default class Hexagons extends Component {
componentDidMount() {
// add click event handler to hexagons
this.hexGroup = d3.select(this.svg).append('g');
this.hexGroup.selectAll('.hex')
.data(this.state.hexData)
.enter()
.append('path')
...
.on('click', d => {
// I'm not a huge fan of D3's global event object,
// but it's what we get :)
d3.event.preventDefault();
d3.event.stopPropagation();
this.setState({
hexData: this.state.hexData.map(hex => toggleHex(d, hex))
});
})
}
componentDidUpdate() {
// animate hexagon color every time the component's state changes
const selection = this.hexGroup.selectAll('.hex')
.data(this.state.hexData)
.selectAll('path')
.transition()
.duration(500)
.attr('fill', d => (d.active ? 'rgb(255, 1, 175)' : 'rgb(60, 60, 60)'));
}
render() {
...
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment