author | ymh <ymh.work@gmail.com> |
Mon, 17 Sep 2018 00:28:58 +0200 | |
changeset 3 | 7af67d500dd5 |
parent 0 | 5f4fcbc80b37 |
permissions | -rw-r--r-- |
0
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
1 |
/* eslint func-names: "off" */ |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
2 |
import React, { Component } from 'react'; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
3 |
import PropTypes from 'prop-types'; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
4 |
import * as d3 from 'd3'; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
5 |
import { withRouter } from 'react-router-dom'; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
6 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
7 |
import './RowChart.scss'; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
8 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
9 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
10 |
/** |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
11 |
* TODO: As a first implementation we have chosen to delagate the barchart DOM drawing to D3. |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
12 |
* This may not be the optimum solution. This may have to be rewrittten to use |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
13 |
* React for elementt creation and D3 as the visualisation kernel. |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
14 |
*/ |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
15 |
class RowChart extends Component { |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
16 |
static propTypes = { |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
17 |
data: PropTypes.PropTypes.arrayOf(PropTypes.object).isRequired, |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
18 |
tagPrefix: PropTypes.string.isRequired, |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
19 |
history: PropTypes.object.isRequired, |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
20 |
} |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
21 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
22 |
componentDidMount() { |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
23 |
this.drawChart(); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
24 |
} |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
25 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
26 |
componentDidUpdate() { |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
27 |
this.drawChart(); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
28 |
} |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
29 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
30 |
drawChart() { |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
31 |
const { node } = this; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
32 |
const { data, tagPrefix } = this.props; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
33 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
34 |
const width = 800; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
35 |
const barHeight = 30; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
36 |
const height = barHeight * data.length; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
37 |
const valueMargin = 4; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
38 |
const yAxisHMargin = 10; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
39 |
const yAxisVMargin = 10; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
40 |
const barVMargin = 10; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
41 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
42 |
const y = d3.scaleBand() |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
43 |
.rangeRound([0, height]) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
44 |
.padding(0.1) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
45 |
.domain(data.map(d => d.tag)); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
46 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
47 |
const yAxis = d3.axisLeft(y); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
48 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
49 |
d3.select(node).selectAll('svg').remove(); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
50 |
const chart = d3.select(node) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
51 |
.append('svg') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
52 |
.attr('width', '100%'); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
53 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
54 |
const barsContainer = chart.append('g') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
55 |
.attr('class', 'bars-container'); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
56 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
57 |
const yAxisContainer = chart.append('g') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
58 |
.attr('class', 'y-axis axis') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
59 |
.call(yAxis); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
60 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
61 |
let yAxisWidth = 0; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
62 |
chart.selectAll('.y-axis text') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
63 |
.each(function () { yAxisWidth = Math.max(yAxisWidth, this.getBBox().width); }); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
64 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
65 |
const x = d3.scaleLinear() |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
66 |
.range([0, width - yAxisWidth - yAxisHMargin]) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
67 |
.domain([0, d3.max(data, d => d.count)]); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
68 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
69 |
const xAxis = d3.axisBottom(x); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
70 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
71 |
const xAxisContainer = chart.append('g') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
72 |
.attr('class', 'y-axis axis') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
73 |
.attr('transform', `translate(${[yAxisWidth + 2 * yAxisHMargin, height + yAxisVMargin]})`) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
74 |
.call(xAxis); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
75 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
76 |
const bar = barsContainer.selectAll('.bars-container') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
77 |
.data(data) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
78 |
.enter().append('g') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
79 |
.attr('transform', (d, i) => `translate(0,${i * barHeight})`) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
80 |
.attr('class', 'graph-bar'); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
81 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
82 |
bar.append('rect') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
83 |
.attr('width', d => x(d.count)) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
84 |
.attr('height', barHeight - barVMargin) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
85 |
.attr('fill', d => d.color) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
86 |
.attr('stroke', d => d.color) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
87 |
.attr('transform', 'translate(0,5)') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
88 |
.on('click', (d) => { |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
89 |
const { history } = this.props; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
90 |
history.push(`/annotations/${tagPrefix}${d.tag}`); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
91 |
}); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
92 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
93 |
bar.append('text') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
94 |
.attr('y', barHeight / 2) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
95 |
.attr('dy', '.35em') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
96 |
.attr('dx', -valueMargin) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
97 |
.attr('text-anchor', 'end') |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
98 |
.text(d => d.count) |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
99 |
.attr('x', function (d) { |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
100 |
const xWidth = this.getBBox().width; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
101 |
return Math.max(xWidth + valueMargin, x(d.count)); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
102 |
}); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
103 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
104 |
yAxisContainer.attr('transform', `translate(${yAxisWidth + yAxisHMargin},0)`); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
105 |
barsContainer.attr('transform', `translate(${yAxisWidth + 2 * yAxisHMargin},0)`); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
106 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
107 |
const totalHeight = height + xAxisContainer.node().getBBox().height + yAxisVMargin; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
108 |
const totalWidth = width + 2 * yAxisHMargin; |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
109 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
110 |
chart.attr('viewBox', [0, 0, totalWidth, totalHeight].join(' ')); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
111 |
} |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
112 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
113 |
render() { |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
114 |
return ( |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
115 |
<div className="row chart-container"> |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
116 |
<div className="col col-12" ref={(elt) => { this.node = elt; }} /> |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
117 |
</div> |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
118 |
); |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
119 |
} |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
120 |
} |
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
121 |
|
5f4fcbc80b37
Create new repository to host all dashboard developments
ymh <ymh.work@gmail.com>
parents:
diff
changeset
|
122 |
export default withRouter(RowChart); |