|
1 | 1 | import React, { Component } from 'react'; |
2 | 2 | import PropTypes from 'prop-types'; |
3 | 3 | import * as d3 from 'd3'; |
4 | | -import tData from './data.tsv'; |
5 | 4 |
|
6 | 5 | class HBarChart extends Component { |
7 | | - constructor(props) { |
8 | | - super(props); |
9 | | - |
10 | | - this.state = { |
11 | | - // svgWidth: props.width, |
12 | | - // svgHeight: props.height, |
13 | | - // svgMargin: props.margin, |
14 | | - // padding: props.padding, |
15 | | - |
16 | | - // xScale: d3 |
17 | | - // .scaleBand() |
18 | | - // .range([props.margin.left, props.width - props.margin.right]) |
19 | | - // .padding(props.padding), |
20 | | - // yScale: d3 |
21 | | - // .scaleLinear() |
22 | | - // .range([props.height - props.margin.bottom, props.margin.top]), |
23 | | - // xAxisRef: null, |
24 | | - // yAxisRef: null, |
25 | | - }; |
26 | | - |
27 | | - // this.xAxis = d3.axisBottom().scale(this.state.xScale); |
28 | | - // this.yAxis = d3 |
29 | | - // .axisRight() |
30 | | - // .scale(this.state.yScale) |
31 | | - // .tickFormat(d => `${d * 100}%`); |
32 | | - } |
33 | | - |
34 | 6 | componentDidMount() { |
35 | | - this.calculateChart(); |
36 | | - }; |
37 | | - |
38 | | - componentDidUpdate() { |
39 | | - // d3.select(this.state.xAxisRef).call(this.xAxis); |
40 | | - // d3.select(this.state.yAxisRef).call(this.yAxis); |
41 | | - } |
42 | | - |
43 | | - // xAxisRef = element => { |
44 | | - // this.setState({ xAxisRef: element }); |
45 | | - // d3.select(element).call(this.xAxis); |
46 | | - // }; |
47 | | - |
48 | | - // yAxisRef = element => { |
49 | | - // this.setState({ yAxisRef: element }); |
50 | | - // d3.select(element).call(this.yAxis); |
51 | | - // }; |
52 | | - |
53 | | - type = d => { |
54 | | - d.value = +d.value; |
55 | | - return d; |
| 7 | + if (this.props.data !== null) |
| 8 | + this.calculateChart(); |
56 | 9 | }; |
57 | 10 |
|
58 | 11 | calculateChart = () => { |
59 | | - var margin = {top: 20, right: 30, bottom: 40, left: 30}, |
60 | | - width = 960 - margin.left - margin.right, |
61 | | - height = 500 - margin.top - margin.bottom; |
62 | | - |
63 | | - var x = d3.scaleLinear() |
64 | | - .range([0, width]); |
65 | | - |
66 | | - var y = d3.scaleBand() |
67 | | - .range([0, height]) |
68 | | - .paddingInner(0.2); |
69 | | - |
70 | | - var xAxis = d3.axisBottom() |
| 12 | + const { data, width, height, margin } = this.props; |
| 13 | + const svgWidth = width - margin.left - margin.right; |
| 14 | + const svgHeight = height - margin.top - margin.bottom; |
| 15 | + |
| 16 | + const x = d3 |
| 17 | + .scaleLinear() |
| 18 | + .range([0, svgWidth]); |
| 19 | + |
| 20 | + const y = d3 |
| 21 | + .scaleBand() |
| 22 | + .range([0, svgHeight]) |
| 23 | + .paddingInner(0.2) |
| 24 | + .paddingOuter(0.2); |
| 25 | + |
| 26 | + const xAxis = d3 |
| 27 | + .axisBottom() |
71 | 28 | .scale(x); |
72 | 29 |
|
73 | | - var yAxis = d3.axisRight() |
| 30 | + const yAxis = d3 |
| 31 | + .axisRight() |
74 | 32 | .scale(y) |
75 | 33 | .tickSize(0) |
76 | 34 | .tickPadding(6); |
77 | 35 |
|
78 | | - var svg = d3.select("#container").append("svg") |
79 | | - .attr("width", width + margin.left + margin.right) |
80 | | - .attr("height", height + margin.top + margin.bottom) |
81 | | - .append("g") |
82 | | - .attr("transform", "translate(" + margin.left + "," + margin.top + ")"); |
83 | | - |
84 | | - d3.tsv(tData, d => ({ |
| 36 | + const svg = d3 |
| 37 | + .select('#container') |
| 38 | + .append('svg') |
| 39 | + .attr('width', svgWidth + margin.left + margin.right) |
| 40 | + .attr('height', svgHeight + margin.top + margin.bottom) |
| 41 | + .append('g') |
| 42 | + .attr('transform', 'translate(' + margin.left + ',' + margin.top + ')'); |
| 43 | + |
| 44 | + d3.tsv(data, d => ({ |
85 | 45 | name: d.name, |
86 | 46 | value: d.value, |
87 | 47 | })) |
88 | 48 | .then(data => { |
89 | 49 | x.domain(d3.extent(data, d => parseInt(d.value))).nice() |
90 | 50 | y.domain(data.map(d => d.name)) |
91 | | - svg.selectAll(".bar") |
92 | | - .data(data) |
93 | | - .enter().append("rect") |
94 | | - .attr("class", d => "bar bar--" + (d.value < 0 ? "negative" : "positive")) |
95 | | - .attr("x", d => x(Math.min(0, d.value))) |
96 | | - .attr("y", d => y(d.name)) |
97 | | - .attr("width", d => Math.abs(x(d.value) - x(0))) |
98 | | - .attr("height", y.bandwidth); |
99 | | - |
100 | | - svg.append("g") |
101 | | - .attr("class", "x axis") |
102 | | - .attr("transform", "translate(0," + height + ")") |
| 51 | + svg.selectAll('.bar') |
| 52 | + .data(data) |
| 53 | + .enter().append('rect') |
| 54 | + .attr('class', d => 'bar bar--' + (d.value < 0 ? 'negative' : 'positive')) |
| 55 | + .attr('x', d => x(Math.min(0, d.value))) |
| 56 | + .attr('y', d => y(d.name)) |
| 57 | + .attr('width', d => Math.abs(x(d.value) - x(0))) |
| 58 | + .attr('height', y.bandwidth); |
| 59 | + |
| 60 | + svg.append('g') |
| 61 | + .attr('class', 'x axis') |
| 62 | + .attr('transform', 'translate(0,' + svgHeight + ')') |
103 | 63 | .call(xAxis); |
104 | 64 |
|
105 | | - svg.append("g") |
106 | | - .attr("class", "y axis") |
107 | | - .attr("transform", "translate(" + x(0) + ",0)") |
| 65 | + svg.append('g') |
| 66 | + .attr('class', 'y axis') |
| 67 | + .attr('transform', 'translate(' + x(0) + ',0)') |
108 | 68 | .call(yAxis); |
109 | 69 | }); |
110 | 70 | } |
111 | 71 |
|
112 | 72 | render() { |
113 | | - const { svgWidth, svgHeight, svgMargin } = this.state; |
114 | 73 | return ( |
115 | | - <div id="container"> |
116 | | - {/* <svg id="hbarchart" width={svgWidth} height={svgHeight}> |
117 | | - <g id="wrapper" transform="translate(40, 20)"> |
118 | | - </g> |
119 | | - <g> |
120 | | - <g |
121 | | - ref={this.xAxisRef} |
122 | | - transform={`translate(0, ${svgHeight - svgMargin.bottom})`} |
123 | | - /> |
124 | | - <g |
125 | | - ref={this.yAxisRef} |
126 | | - transform={`translate(${svgMargin.left}, 0)`} /> |
127 | | - </g> |
128 | | - </svg> */} |
129 | | - </div> |
| 74 | + <div id="container" /> |
130 | 75 | ); |
131 | 76 | } |
132 | 77 | } |
133 | 78 |
|
134 | 79 | HBarChart.propTypes = { |
| 80 | + data: PropTypes.string , |
135 | 81 | width: PropTypes.number, |
136 | 82 | height: PropTypes.number, |
137 | 83 | margin: PropTypes.object, |
138 | | - padding: PropTypes.number, |
139 | 84 | }; |
140 | 85 |
|
141 | 86 | HBarChart.defaultProps = { |
| 87 | + data: null, |
142 | 88 | width: 1000, |
143 | 89 | height: 600, |
144 | 90 | margin: { top: 20, right: 5, bottom: 20, left: 35 }, |
145 | | - padding: 0.2, |
146 | 91 | }; |
147 | 92 |
|
148 | 93 | export default HBarChart; |
0 commit comments