-
Notifications
You must be signed in to change notification settings - Fork 1
/
LineChartsContainer.jsx
149 lines (131 loc) · 4.25 KB
/
LineChartsContainer.jsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import React, { Component } from 'react';
import PropTypes from 'prop-types';
import { max } from 'd3';
import { connect } from 'react-redux';
import { setTrendAggregation, setDateRangeGroupOne, setDateRangeGroupTwo } from '../../actions';
import LineChartWrapper from '../../containers/LineChartWrapper';
import ReferenceEntitySelect from '../../containers/ReferenceEntitySelect';
import { formatDateMonth } from '../../common/d3Utils';
const mapStateToProps = ({ dateRanges, trendAggMonths }) => ({
periodA: dateRanges.period1,
periodB: dateRanges.period2,
trendAggMonths,
});
/**
* Class that houses the the Line Charts
* Uses internal state to track entity values & compute max y values for primary & secondary entities
and reference entity, so that both charts share the same y domains
*/
class LineChartsContainer extends Component {
static propTypes = {
trendAggMonths: PropTypes.number.isRequired,
setTrendAggregation: PropTypes.func.isRequired,
periodA: PropTypes.shape({
endDate: PropTypes.instanceOf(Date),
startDate: PropTypes.instanceOf(Date),
}),
periodB: PropTypes.shape({
endDate: PropTypes.instanceOf(Date),
startDate: PropTypes.instanceOf(Date),
}),
};
static defaultProps = {
periodA: {},
periodB: {},
};
constructor() {
super();
this.state = {
period1Y: [],
period2Y: [],
period1Y2: [],
period2Y2: [],
};
this.setPeriodYValue = this.setPeriodYValue.bind(this);
this.handleChangeAggMonths = this.handleChangeAggMonths.bind(this);
}
setPeriodYValue(type, values) {
if (values && values.length) {
this.setState({
[type]: values,
});
}
}
handleChangeAggMonths(event) {
const months = parseInt(event.target.value, 10);
this.props.setTrendAggregation(months);
}
render() {
const { period1Y, period2Y, period1Y2, period2Y2 } = this.state;
const { trendAggMonths } = this.props;
const { periodA, periodB } = this.props;
const style = {
height: '100%',
width: '100%',
};
// both line charts should share the same y domain for primary secondary & reference,
// so compute the max value of each here then pass it down to the charts
const y = [...period1Y, ...period2Y];
const y2 = [...period1Y2, ...period2Y2];
const entitiesMax = max(y, d => d.count);
const citywideMax = max(y2, d => d.count);
const xaxisselector = (
<span className="TrendMonthsAggSelector">
<label htmlFor="trend-months-agg-selector">AGGREGATE EVERY</label>
<select
id="trend-months-agg-selector"
value={trendAggMonths}
onChange={this.handleChangeAggMonths}
>
<option value="1">Month</option>
<option value="3">3 Months</option>
<option value="6">6 Months</option>
<option value="12">12 Months</option>
</select>
</span>
);
// inspect the period A and B date ranges
// make a warning message if they're of different duration and/or months
let startmonthA = '';
let startmonthB = '';
let periodsequalwarning = null;
if (periodA && periodB) {
startmonthA = formatDateMonth(periodA.startDate);
startmonthB = formatDateMonth(periodB.startDate);
}
if (startmonthA !== startmonthB) {
periodsequalwarning = (
<div className="PeriodsNotEqualWarning">
It's best to select two periods starting in the same month.
</div>
);
}
return (
<div className="LineChartsContainer scroll" style={style}>
<LineChartWrapper
period="period1"
yMax={entitiesMax}
y2Max={citywideMax}
setMaxY={this.setPeriodYValue}
trendAggMonths={parseInt(trendAggMonths, 10)}
>
{xaxisselector}
<ReferenceEntitySelect />
</LineChartWrapper>
{periodsequalwarning}
<LineChartWrapper
period="period2"
yMax={entitiesMax}
y2Max={citywideMax}
setMaxY={this.setPeriodYValue}
trendAggMonths={parseInt(trendAggMonths, 10)}
/>
</div>
);
}
}
export default connect(mapStateToProps, {
setTrendAggregation,
setDateRangeGroupOne,
setDateRangeGroupTwo,
})(LineChartsContainer);