1
+ import React from 'react' ;
2
+
3
+
4
+ // PropTypes is a separate package now:
5
+ import PropTypes from 'prop-types' ;
6
+
7
+ class HorizontalBulletGraph extends React . Component {
8
+ render ( ) {
9
+ // Normalize values which exceed scaleMax prop
10
+ let badVal = Math . min ( this . props . badVal , this . props . scaleMax ) ,
11
+ satisfactoryVal = Math . min ( this . props . satisfactoryVal , this . props . scaleMax ) ,
12
+ performanceVal = Math . min ( this . props . performanceVal , this . props . scaleMax ) ,
13
+ symbolMarker = Math . min ( this . props . symbolMarker , this . props . scaleMax ) ;
14
+
15
+ // Scale tick component props to specified component width prop
16
+ let widthScale = this . props . width /
17
+ ( this . props . scaleMax - this . props . scaleMin ) ;
18
+
19
+ let horizontalBulletGraphStyles = {
20
+ display : "flex" ,
21
+ justifyContent : "flex-end"
22
+ } ;
23
+
24
+ let graphStyles = {
25
+ position : "relative"
26
+ } ;
27
+
28
+ let goodValStyles = {
29
+ backgroundColor : this . props . goodColor ,
30
+ height : this . props . height + "px" ,
31
+ width : this . props . width + "px" ,
32
+ zIndex : 1
33
+ } ;
34
+
35
+ let titleStyles = {
36
+ fontSize : "18px" ,
37
+ lineHeight : this . props . height + "px" ,
38
+ margin : "0" ,
39
+ textAlign : "right" ,
40
+ whiteSpace : "nowrap"
41
+ } ;
42
+
43
+ let textLabelStyles = {
44
+ fontSize : "12px" ,
45
+ margin : "0" ,
46
+ textAlign : "right"
47
+ } ;
48
+
49
+ let legendStyles = {
50
+ paddingRight : "10px"
51
+ } ;
52
+
53
+ let satisfactoryValStyles = {
54
+ backgroundColor : this . props . satisfactoryColor ,
55
+ height : this . props . height + "px" ,
56
+ left : "0" ,
57
+ position : "absolute" ,
58
+ top : "0" ,
59
+ width : ( this . props . satisfactoryVal - this . props . scaleMin ) * widthScale + "px" ,
60
+ zIndex : 2
61
+ } ;
62
+
63
+ let badValStyles = {
64
+ backgroundColor : this . props . badColor ,
65
+ height : this . props . height + "px" ,
66
+ left : "0" ,
67
+ position : "absolute" ,
68
+ top : "0" ,
69
+ width : ( badVal - this . props . scaleMin ) * widthScale + "px" ,
70
+ zIndex : 3
71
+ } ;
72
+
73
+ let performanceWidth = ( performanceVal - this . props . scaleMin ) * widthScale ;
74
+
75
+ let performanceValStyles = {
76
+ backgroundColor : "black" ,
77
+ height : this . props . height / 3 + "px" ,
78
+ left : "0" ,
79
+ marginBottom : this . props . height / 3 + "px" ,
80
+ marginTop : this . props . height / 3 + "px" ,
81
+ position : "absolute" ,
82
+ top : "0" ,
83
+ width : performanceWidth + "px" ,
84
+ zIndex : 4
85
+ } ;
86
+
87
+ let symbolMarkerWidth = this . props . width * 0.01 ,
88
+ // Should not exceed boundaries qualitative range boundaries
89
+ symbolMarkerPos = ( symbolMarker - this . props . scaleMin ) * widthScale * 0.99 ;
90
+
91
+ let symbolMarkerStyles = {
92
+ backgroundColor : "black" ,
93
+ left : symbolMarkerPos + "px" ,
94
+ height : this . props . height * 0.8 + "px" ,
95
+ marginBottom : this . props . height * 0.1 + "px" ,
96
+ marginTop : this . props . height * 0.1 + "px" ,
97
+ position : "absolute" ,
98
+ top : "0" ,
99
+ width : symbolMarkerWidth + "px" ,
100
+ zIndex : 4
101
+ } ;
102
+
103
+ let quantitativeScaleStyles = {
104
+ left : "0" ,
105
+ position : "absolute" ,
106
+ top : this . props . height + "px"
107
+ } ;
108
+
109
+ let tickIncrement = ( this . props . scaleMax - this . props . scaleMin ) / 5 ;
110
+
111
+ let ticks = Array . from ( { length : 6 } , ( tick , i ) => {
112
+ let tickLeft = parseInt ( i * tickIncrement * widthScale * 0.996 , 10 ) ,
113
+ numLeft = tickLeft - 50 ,
114
+ tickWidth = this . props . width * 0.005 ;
115
+
116
+ return {
117
+ key : i ,
118
+ numStyles : {
119
+ fontSize : "14px" ,
120
+ left : numLeft + "px" ,
121
+ paddingLeft : "2px" ,
122
+ position : "absolute" ,
123
+ textAlign : "center" ,
124
+ top : "0" ,
125
+ width : "100px"
126
+ } ,
127
+ tickStyles : {
128
+ backgroundColor : "black" ,
129
+ height : "10px" ,
130
+ left : tickLeft + "px" ,
131
+ position : "absolute" ,
132
+ textAlign : "center" ,
133
+ top : "-0px" ,
134
+ width : tickWidth + "px"
135
+ } ,
136
+ value : i * tickIncrement + this . props . scaleMin
137
+ }
138
+ } ) ;
139
+
140
+ return ( <
141
+ div style = { horizontalBulletGraphStyles } >
142
+
143
+ <
144
+ div style = { legendStyles } >
145
+ <
146
+ p style = { titleStyles } > { this . props . title } < / p > <
147
+ p style = { textLabelStyles } > { this . props . textLabel } < / p > < /
148
+ div >
149
+
150
+ <
151
+ div className = "Graph"
152
+ style = { graphStyles } >
153
+ <
154
+ div style = { goodValStyles } > < / div >
155
+
156
+ {
157
+ ! isNaN ( satisfactoryVal ) && < div style = { satisfactoryValStyles } > < / div > }
158
+
159
+ {
160
+ ! isNaN ( badVal ) && < div style = { badValStyles } > < / div > }
161
+
162
+ {
163
+ ! isNaN ( performanceVal ) && < div style = { performanceValStyles } > < / div > }
164
+
165
+ {
166
+ ! isNaN ( symbolMarker ) && < div style = { symbolMarkerStyles } > < / div > }
167
+
168
+ <
169
+ div className = "QuantitativeScale"
170
+ style = { quantitativeScaleStyles } >
171
+
172
+ {
173
+ ticks . map ( ( tick ) => ( <
174
+ div key = { tick . key }
175
+ style = { tick . tickStyles } >
176
+ <
177
+ / div >
178
+ ))
179
+ }
180
+
181
+ {
182
+ ticks . map ( ( tick ) => ( <
183
+ p key = { tick . key }
184
+ style = { tick . numStyles } > { this . props . unitsPrefix || '' } { tick . value } { this . props . unitsSuffix || '' } <
185
+ / p >
186
+ ))
187
+ }
188
+
189
+ <
190
+ / div > < /
191
+ div >
192
+
193
+ <
194
+ / div >
195
+ );
196
+ }
197
+ } ;
198
+
199
+ export default HorizontalBulletGraph ;
0 commit comments