Skip to content

Instantly share code, notes, and snippets.

@ja0nz
Created June 22, 2017 18:01
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 ja0nz/8a1d97c5034ee0f220193e7e5010126c to your computer and use it in GitHub Desktop.
Save ja0nz/8a1d97c5034ee0f220193e7e5010126c to your computer and use it in GitHub Desktop.
Mike Bostocks BarChart in React - https://bl.ocks.org/mbostock/3885304
import React, { Component } from 'react';
import { tsv } from 'd3-request';
import { scaleBand, scaleLinear } from 'd3-scale';
import { max } from 'd3-array';
import { select, } from 'd3-selection';
import { axisBottom, axisLeft } from 'd3-axis';
import { futurize } from 'futurize';
import { Future } from 'ramda-fantasy';
import './BarChart.css';
const read = futurize(Future)(tsv);
// <BarChart data="data.tsv" width="960" height="500" />
class BarChart extends Component {
constructor(props){
super(props)
this.createBarChart = this.createBarChart.bind(this)
}
setData(s) {
this.data = s;
}
componentDidMount() {
read(this.props.data)
.chain(a =>
Future.of(a.map(o => (
{ ...o, frequency: Number(o.frequency)}))))
.map(a => {
a.columns = Object.keys(a[0]);
return a;
})
.fork(e => console.log(e), s => {
this.setData(s); this.createBarChart();
});
}
componentDidUpdate() {
this.createBarChart();
}
createBarChart() {
const node = this.node;
const margin = {top: 20, right: 20, bottom: 30, left: 40},
width = this.props.width - margin.left - margin.right,
height = this.props.height - margin.top - margin.bottom,
x = scaleBand().rangeRound([0, width]).padding(0.1),
y = scaleLinear().rangeRound([height, 0]);
select(node)
.append("g")
.attr("transform", "translate(" + margin.left + "," + margin.top + ")");
x.domain(this.data.map(d => d.letter));
y.domain([0, max(this.data, d => d.frequency)]);
const g = select(node).select('g');
g.append("g")
.attr("class", "axis axis--x")
.attr("transform", "translate(0," + height + ")")
.call(axisBottom(x));
g.append("g")
.attr("class", "axis axis--y")
.call(axisLeft(y).ticks(10, "%"))
.append("text")
.attr("transform", "rotate(-90)")
.attr("y", 6)
.attr("dy", "0.71em")
.attr("text-anchor", "end")
.text("Frequency");
g.selectAll(".bar")
.data(this.data)
.enter()
.append("rect")
.attr("class", "bar")
.attr("x", d => x(d.letter))
.attr("y", d => y(d.frequency))
.attr("width", x.bandwidth())
.attr("height", d => height - y(d.frequency));
}
render() {
return (
<svg
ref={node => this.node = node}
width={this.props.width}
height={this.props.height}>
</svg>
);
}
}
export default BarChart;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment