February 4, 2016
In this blog, we will see how to plot a simple line chart using ReactJS and D3JS.
If you are not familiar with ReactJS then please take a look at official ReactJS webpage. You can also look at our Learn ReactJS in steps video series.
D3.js is a Javascript library used to create interactive, dynamic visualizations.
Let's take a step by step look at how we can integrate ReactJS with D3JS to plot some interactive visualizations.
We will be using JSFiddle example from ReactJS Docs to begin with. Fork the JSFiddle example and you should be good to go.
We will be using D3.js from Cloudflare CDN. Add D3.js as an external resource as shown in the image given below and type the following URL as an external resource.
https://cdnjs.cloudflare.com/ajax/libs/d3/3.5.12/d3.js
Now let's try to draw a Line Chart using D3.js.
Let's create a Line
component that renders line path for the data points provided.
const Line = React.createClass({
propTypes: {
path: React.PropTypes.string.isRequired,
stroke: React.PropTypes.string,
fill: React.PropTypes.string,
strokeWidth: React.PropTypes.number,
},
getDefaultProps() {
return {
stroke: "blue",
fill: "none",
strokeWidth: 3,
};
},
render() {
let { path, stroke, fill, strokeWidth } = this.props;
return (
<path d={path} fill={fill} stroke={stroke} strokeWidth={strokeWidth} />
);
},
});
Here in above code,
Line
component renders an
SVG path.
Path data
d
is generated using
D3 path functions.
Let's create another component DataSeries
that will render Line
component
for each series of data provided.
This generates path
based on xScale
and yScale
generated for plotting a line chart.
const DataSeries = React.createClass({
propTypes: {
colors: React.PropTypes.func,
data: React.PropTypes.object,
interpolationType: React.PropTypes.string,
xScale: React.PropTypes.func,
yScale: React.PropTypes.func,
},
getDefaultProps() {
return {
data: [],
interpolationType: "cardinal",
colors: d3.scale.category10(),
};
},
render() {
let { data, colors, xScale, yScale, interpolationType } = this.props;
let line = d3.svg
.line()
.interpolate(interpolationType)
.x((d) => {
return xScale(d.x);
})
.y((d) => {
return yScale(d.y);
});
let lines = data.points.map((series, id) => {
return <Line path={line(series)} stroke={colors(id)} key={id} />;
});
return (
<g>
<g>{lines}</g>
</g>
);
},
});
Here in above code d3.svg.line creates a new line generator which expects input as a two-element array of numbers.
Now we will create LineChart
component that will calculate xScale
, yScale
based on data
and
will render DataSeries
by passing xScale
, yScale
, data
(input x,y values), width, height for the chart.
const LineChart = React.createClass({
propTypes: {
width: React.PropTypes.number,
height: React.PropTypes.number,
data: React.PropTypes.object.isRequired,
},
getDefaultProps() {
return {
width: 600,
height: 300,
};
},
render() {
let { width, height, data } = this.props;
let xScale = d3.scale
.ordinal()
.domain(data.xValues)
.rangePoints([0, width]);
let yScale = d3.scale
.linear()
.range([height, 10])
.domain([data.yMin, data.yMax]);
return (
<svg width={width} height={height}>
<DataSeries
xScale={xScale}
yScale={yScale}
data={data}
width={width}
height={height}
/>
</svg>
);
},
});
Here d3.scale.ordinal constructs an ordinal scale that can have discrete domain while d3.scale.linear constructs a linear quantitative scale.
You can learn more about D3 Quantitative scales here.
Now we need to call LineDataSeries
component with the data.
let data = {
points: [
[
{ x: 0, y: 20 },
{ x: 1, y: 30 },
{ x: 2, y: 10 },
{ x: 3, y: 5 },
{ x: 4, y: 8 },
{ x: 5, y: 15 },
{ x: 6, y: 10 },
],
[
{ x: 0, y: 8 },
{ x: 1, y: 5 },
{ x: 2, y: 20 },
{ x: 3, y: 12 },
{ x: 4, y: 4 },
{ x: 5, y: 6 },
{ x: 6, y: 2 },
],
[
{ x: 0, y: 0 },
{ x: 1, y: 5 },
{ x: 2, y: 8 },
{ x: 3, y: 2 },
{ x: 4, y: 6 },
{ x: 5, y: 4 },
{ x: 6, y: 2 },
],
],
xValues: [0, 1, 2, 3, 4, 5, 6],
yMin: 0,
yMax: 30,
};
ReactDOM.render(
<LineChart data={data} width={600} height={300} />,
document.getElementById("container")
);
An element with id container
is replaced with content rendered by LineChart
.
If we take a look at the output now, we see how the Line Chart gets plotted.
To build complex visualizations in a modularized fashion, we can use one of the open source libraries mentioned below based on their advantages and disadvantages.
Here are two popular open source ReactJS + D3.JS projects.
Pros
Cons
Pros
Cons
Below is final working example of JSFiddle built in the post.
If this blog was helpful, check out our full blog archive.