Skip to content

Instantly share code, notes, and snippets.

@martgnz
Created July 18, 2018 12:42
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save martgnz/c28d1dd436a770b0b262fb53d3334024 to your computer and use it in GitHub Desktop.
Save martgnz/c28d1dd436a770b0b262fb53d3334024 to your computer and use it in GitHub Desktop.
D3 and React with D3Container
import React, { Component } from 'react';
export default class D3Container extends Component {
constructor(...args) {
super(...args);
this.d3Render = this.d3Render.bind(this);
}
componentDidMount() {
this.d3Render(this.container);
}
componentDidUpdate() {
this.d3Render(this.container);
}
static get defaultProps() {
return {
container: 'svg',
width: 640,
height: 300,
className: 'd3-container',
};
}
d3Render(container) {
// extend this method
// eslint-disable-next-line no-console
console.log('d3 render with container', container);
}
render() {
const { container, width, height, className } = this.props;
return React.createElement(container, {
width: container === 'svg' ? width : undefined,
height: container === 'svg' ? height : undefined,
className,
ref: d3Container => {
this.container = d3Container;
},
});
}
}
import React from 'react';
import { select } from 'd3-selection';
import { axisBottom } from 'd3-axis';
import { scaleLinear } from 'd3-scale';
import { range } from 'd3-array';
import d3Container from './d3-container';
export default class SimpleChart extends d3Container {
d3Render() {
select(this.xAxisGroup).call(this.xAxis);
select(this.circles)
.selectAll('circle')
.data(this.data)
.enter()
.append('circle')
.attr('r', 4)
.attr('fill', 'steelblue')
.attr('cx', d => this.x(d))
.attr('cy', this.height / 2);
}
render() {
const margin = { top: 20, right: 20, bottom: 20, left: 20 };
this.width = 960 - margin.left - margin.right;
this.height = 100 - margin.top - margin.bottom;
this.data = range(10, 100, 10);
this.x = scaleLinear()
.range([0, this.width])
.domain([0, 100]);
this.xAxis = axisBottom(this.x).ticks(5);
return (
<svg
width={this.width + margin.left + margin.right}
height={this.height + margin.top + margin.bottom}
>
<g transform={`translate(${margin.left},${margin.top})`}>
<g
className="x axis"
transform={`translate(0, ${this.height})`}
ref={chart => {
this.xAxisGroup = chart;
}}
/>
<g
ref={chart => {
this.circles = chart;
}}
/>
<text
textAnchor="middle"
x={this.width / 2}
y={this.height / 2}
dy={-15}
>
This might be an interesting point
</text>
</g>
</svg>
);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment