@@ -24,10 +24,10 @@ import { Arc, arc, DefaultArcObject } from 'd3-shape';
24
24
[attr.d]="rendererData.data.valueArc"
25
25
[attr.fill]="rendererData.data.threshold.color"
26
26
/>
27
- <text x="0" y="0 " class="value-display" [attr.fill]="rendererData.data.threshold.color">
27
+ <text x="0" y="-4 " class="value-display" [attr.fill]="rendererData.data.threshold.color">
28
28
{{ rendererData.data.value }}
29
29
</text>
30
- <text x="0" y="24 " class="label-display">{{ rendererData.data.threshold.label }}</text>
30
+ <text x="0" y="20 " class="label-display">{{ rendererData.data.threshold.label }}</text>
31
31
</g>
32
32
</g>
33
33
</svg>
@@ -37,10 +37,10 @@ import { Arc, arc, DefaultArcObject } from 'd3-shape';
37
37
changeDetection : ChangeDetectionStrategy . OnPush
38
38
} )
39
39
export class GaugeComponent implements OnChanges {
40
- private static readonly GAUGE_RING_WIDTH : number = 20 ;
40
+ private static readonly GAUGE_RING_WIDTH : number = 15 ;
41
41
private static readonly GAUGE_ARC_CORNER_RADIUS : number = 10 ;
42
- private static readonly GAUGE_AXIS_PADDING : number = 30 ;
43
42
private static readonly GAUGE_MIN_RADIUS_TO_SHOW_PATH : number = 80 ;
43
+ private static readonly EXTRA_ARC_ANGLE : number = Math . PI / 12 ;
44
44
45
45
@Input ( )
46
46
public value ?: number ;
@@ -76,7 +76,7 @@ export class GaugeComponent implements OnChanges {
76
76
const radius = this . buildRadius ( boundingBox ) ;
77
77
78
78
return {
79
- origin : this . buildOrigin ( boundingBox ) ,
79
+ origin : this . buildOrigin ( boundingBox . width , radius ) ,
80
80
radius : radius ,
81
81
backgroundArc : this . buildBackgroundArc ( radius ) ,
82
82
data : this . buildGaugeData ( radius , inputData )
@@ -87,8 +87,8 @@ export class GaugeComponent implements OnChanges {
87
87
return this . buildArcGenerator ( ) ( {
88
88
innerRadius : radius - GaugeComponent . GAUGE_RING_WIDTH ,
89
89
outerRadius : radius ,
90
- startAngle : - Math . PI / 2 ,
91
- endAngle : Math . PI / 2
90
+ startAngle : - Math . PI / 2 - GaugeComponent . EXTRA_ARC_ANGLE ,
91
+ endAngle : Math . PI / 2 + GaugeComponent . EXTRA_ARC_ANGLE
92
92
} ) ! ;
93
93
}
94
94
@@ -107,8 +107,8 @@ export class GaugeComponent implements OnChanges {
107
107
return this . buildArcGenerator ( ) ( {
108
108
innerRadius : radius - GaugeComponent . GAUGE_RING_WIDTH ,
109
109
outerRadius : radius ,
110
- startAngle : - Math . PI / 2 ,
111
- endAngle : - Math . PI / 2 + ( inputData . value / inputData . maxValue ) * Math . PI
110
+ startAngle : - Math . PI / 2 - GaugeComponent . EXTRA_ARC_ANGLE ,
111
+ endAngle : - Math . PI / 2 - GaugeComponent . EXTRA_ARC_ANGLE + ( inputData . value / inputData . maxValue ) * Math . PI
112
112
} ) ! ;
113
113
}
114
114
@@ -117,13 +117,32 @@ export class GaugeComponent implements OnChanges {
117
117
}
118
118
119
119
private buildRadius ( boundingBox : ClientRect ) : number {
120
- return Math . min ( boundingBox . height - GaugeComponent . GAUGE_AXIS_PADDING , boundingBox . width / 2 ) ;
120
+ const width = boundingBox . width ;
121
+ const height = boundingBox . height ;
122
+
123
+ if ( height > width / 2 ) {
124
+ /**
125
+ * Since height > width > 2, radius can be treated as (width / 2), but only for semi-circles
126
+ *
127
+ * If there is an extra angle added to the semicircle,
128
+ * radius + extra arc length can over shoots the height
129
+ *
130
+ * If radius + extra arc length over shoots the height, then radius
131
+ * needs to be calculated using the provided height, instead of width / 2
132
+ */
133
+ const radius = width / 2 ;
134
+ const extraArcHeight = this . calculateExtraArcLength ( radius ) ;
135
+
136
+ return extraArcHeight + radius <= height ? radius : this . calculateRadius ( height ) ;
137
+ }
138
+
139
+ return this . calculateRadius ( height ) ;
121
140
}
122
141
123
- private buildOrigin ( boundingBox : ClientRect ) : Point {
142
+ private buildOrigin ( width : number , radius : number ) : Point {
124
143
return {
125
- x : boundingBox . width / 2 ,
126
- y : boundingBox . height - GaugeComponent . GAUGE_AXIS_PADDING
144
+ x : width / 2 ,
145
+ y : radius
127
146
} ;
128
147
}
129
148
@@ -142,6 +161,24 @@ export class GaugeComponent implements OnChanges {
142
161
}
143
162
}
144
163
}
164
+
165
+ private calculateExtraArcLength ( radius : number ) : number {
166
+ return radius * GaugeComponent . EXTRA_ARC_ANGLE ;
167
+ }
168
+
169
+ /**
170
+ * We want to fit gauge within a specified height
171
+ * Approximating arc length, as the extra height required
172
+ * to render the EXTRA_ARC_ANGLE in the gauge
173
+ *
174
+ * height = radius + arc length
175
+ * height = radius + radius * EXTRA_ARC_ANGLE
176
+ * radius = height / (1 + EXTRA_ARC_ANGLE)
177
+ */
178
+
179
+ private calculateRadius ( height : number ) : number {
180
+ return height / ( 1 + GaugeComponent . EXTRA_ARC_ANGLE ) ;
181
+ }
145
182
}
146
183
147
184
export interface GaugeThreshold {
0 commit comments