@hpcc-js/chart 2.86.3 → 2.86.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (84) hide show
  1. package/LICENSE +43 -43
  2. package/README.md +93 -93
  3. package/dist/index.es6.js +2 -2
  4. package/dist/index.es6.js.map +1 -1
  5. package/dist/index.js +2 -2
  6. package/dist/index.js.map +1 -1
  7. package/dist/index.min.js +1 -1
  8. package/dist/index.min.js.map +1 -1
  9. package/package.json +5 -5
  10. package/src/Area.md +176 -176
  11. package/src/Area.ts +12 -12
  12. package/src/Axis.css +34 -34
  13. package/src/Axis.ts +733 -733
  14. package/src/Bar.md +90 -90
  15. package/src/Bar.ts +9 -9
  16. package/src/Bubble.css +16 -16
  17. package/src/Bubble.md +69 -69
  18. package/src/Bubble.ts +191 -191
  19. package/src/BubbleXY.ts +14 -14
  20. package/src/Bullet.css +60 -60
  21. package/src/Bullet.md +104 -104
  22. package/src/Bullet.ts +167 -167
  23. package/src/Column.css +17 -17
  24. package/src/Column.md +90 -90
  25. package/src/Column.ts +659 -659
  26. package/src/Contour.md +88 -88
  27. package/src/Contour.ts +97 -97
  28. package/src/D3Cloud.ts +400 -400
  29. package/src/Gantt.md +119 -119
  30. package/src/Gantt.ts +14 -14
  31. package/src/Gauge.md +148 -148
  32. package/src/Gauge.ts +358 -358
  33. package/src/HalfPie.md +62 -62
  34. package/src/HalfPie.ts +26 -26
  35. package/src/Heat.md +42 -42
  36. package/src/Heat.ts +283 -283
  37. package/src/HexBin.css +9 -9
  38. package/src/HexBin.md +88 -88
  39. package/src/HexBin.ts +139 -139
  40. package/src/Line.css +6 -6
  41. package/src/Line.md +170 -170
  42. package/src/Line.ts +14 -14
  43. package/src/Pie.css +23 -23
  44. package/src/Pie.md +88 -88
  45. package/src/Pie.ts +503 -503
  46. package/src/QuarterPie.md +61 -61
  47. package/src/QuarterPie.ts +35 -35
  48. package/src/QuartileCandlestick.md +129 -129
  49. package/src/QuartileCandlestick.ts +349 -349
  50. package/src/Radar.css +15 -15
  51. package/src/Radar.md +104 -104
  52. package/src/Radar.ts +336 -336
  53. package/src/RadialBar.css +25 -25
  54. package/src/RadialBar.md +91 -91
  55. package/src/RadialBar.ts +212 -212
  56. package/src/Scatter.css +16 -16
  57. package/src/Scatter.md +163 -163
  58. package/src/Scatter.ts +376 -376
  59. package/src/StatChart.md +117 -117
  60. package/src/StatChart.ts +253 -253
  61. package/src/Step.md +163 -163
  62. package/src/Step.ts +12 -12
  63. package/src/Summary.css +56 -56
  64. package/src/Summary.md +219 -219
  65. package/src/Summary.ts +322 -322
  66. package/src/SummaryC.md +154 -154
  67. package/src/SummaryC.ts +240 -240
  68. package/src/WordCloud.css +3 -3
  69. package/src/WordCloud.md +144 -144
  70. package/src/WordCloud.ts +263 -263
  71. package/src/XYAxis.css +41 -41
  72. package/src/XYAxis.md +149 -149
  73. package/src/XYAxis.ts +803 -803
  74. package/src/__package__.ts +3 -3
  75. package/src/__tests__/heat.ts +71 -71
  76. package/src/__tests__/index.ts +3 -3
  77. package/src/__tests__/pie.ts +20 -20
  78. package/src/__tests__/stat.ts +16 -16
  79. package/src/__tests__/test3.ts +69 -69
  80. package/src/index.ts +27 -27
  81. package/src/test.ts +71 -71
  82. package/types/__package__.d.ts +2 -2
  83. package/types/__package__.d.ts.map +1 -1
  84. package/types-3.4/__package__.d.ts +2 -2
package/src/Gauge.ts CHANGED
@@ -1,358 +1,358 @@
1
- import { publish, SVGWidget } from "@hpcc-js/common";
2
- import { format as d3Format } from "d3-format";
3
- import { interpolate as d3Interpolate, interpolateHcl as d3InterpolateHcl } from "d3-interpolate";
4
- import { scaleLinear } from "d3-scale";
5
- import { Arc, arc as d3Arc, DefaultArcObject } from "d3-shape";
6
- import { annotation as d3Annotation, annotationCalloutElbow } from "d3-svg-annotation";
7
-
8
- function value2Angle(value: number): number {
9
- return (value - 0.5) * .65 * 2 * Math.PI;
10
- }
11
-
12
- function pointOnArc(angle: number, radius: number): { x: number, y: number } {
13
- return {
14
- x: Math.cos(angle - Math.PI / 2) * radius,
15
- y: Math.sin(angle - Math.PI / 2) * radius
16
- };
17
- }
18
-
19
- function indicatorTranslate(angle: number, radius: number, inner: boolean = false) {
20
- const point = pointOnArc(angle, radius);
21
- const rotation = angle * 180 / Math.PI + (inner === true ? 180 : 0);
22
- return `translate(${point.x}, ${point.y}) rotate(${rotation})`;
23
- }
24
-
25
- type IndicatorDatum = { angle: number };
26
- function indicatorTween(newAngle: number, radius: number, inner: boolean = false) {
27
- return function (d: IndicatorDatum) {
28
- const interpolate = d3Interpolate(d.angle, newAngle);
29
- d.angle = newAngle;
30
- return function (t: number) {
31
- return indicatorTranslate(interpolate(t), radius, inner);
32
- };
33
- };
34
- }
35
-
36
- function arcTween(startAngle: number, endAngle: number, arc: Arc<any, DefaultArcObject>) {
37
- return function (d: DefaultArcObject) {
38
- const startInterpolate = d3Interpolate(d.startAngle, startAngle);
39
- const endInterpolate = d3Interpolate(d.endAngle, endAngle);
40
- return function (t: number): string {
41
- d.startAngle = startInterpolate(t);
42
- d.endAngle = endInterpolate(t);
43
- return arc(d)!;
44
- };
45
- };
46
- }
47
-
48
- export class Gauge extends SVGWidget {
49
-
50
- private _d3Arc: Arc<any, DefaultArcObject> = d3Arc()
51
- .innerRadius(85)
52
- .outerRadius(100)
53
- ;
54
- private _colorScale = scaleLinear<string, string>()
55
- .interpolate(d3InterpolateHcl)
56
- ;
57
-
58
- protected _usageArc: any;
59
- protected _meanArc: any;
60
- protected _freeArc: any;
61
- protected _indInner: any;
62
- protected _indOuter: any;
63
- protected _centerTextG: any;
64
- protected _centerText: any;
65
- protected _bottomText: any;
66
- protected _tooltipG: any;
67
- protected _mainTooltip: any;
68
-
69
- @publish("", "string")
70
- title: publish<this, string>;
71
-
72
- @publish("", "string")
73
- titleDescription: publish<this, string>;
74
-
75
- @publish(128, "number")
76
- maxDiameter: publish<this, number>;
77
-
78
- @publish(0, "number")
79
- value: publish<this, number>;
80
-
81
- @publish("", "string")
82
- valueDescription: publish<this, string>;
83
-
84
- @publish(false, "boolean")
85
- showTick: publish<this, boolean>;
86
-
87
- @publish(0, "number")
88
- tickValue: publish<this, number>;
89
-
90
- @publish("", "string")
91
- tickValueDescription: publish<this, string>;
92
-
93
- @publish("", "string")
94
- tooltip: publish<this, string>;
95
-
96
- constructor() {
97
- super();
98
- }
99
-
100
- protected tip(d: any) {
101
- if (d === null || d.label === "") {
102
- this._tooltipG
103
- .transition()
104
- .style("opacity", 0)
105
- .on("interrupt end", () => {
106
- this._tooltipG
107
- .selectAll("g")
108
- .remove()
109
- ;
110
- })
111
- ;
112
- } else {
113
- this._tooltipG
114
- .interrupt()
115
- .style("opacity", 1)
116
- ;
117
- d.w = (this._centerText.datum() as any).w + 10;
118
- let lineType = "horizontal";
119
- let xOffset = 0;
120
- let yOffset = 5;
121
- let padding: number | undefined = 5;
122
- if (d.y >= 5 && d.y <= 25) {
123
- xOffset = d.x < 0 ? -d.w / 2 : d.w / 2;
124
- yOffset = 12.5;
125
- padding = undefined;
126
- lineType = "vertical";
127
- } else if (d.y > 25) {
128
- yOffset = 25;
129
- padding = 0;
130
- }
131
- const annotationtip = d3Annotation()
132
- .type(annotationCalloutElbow)
133
- .annotations([{
134
- data: d,
135
- dx: -d.x + xOffset,
136
- dy: -d.y + yOffset,
137
- color: "black",
138
- note: {
139
- label: d.label,
140
- lineType,
141
- padding,
142
- align: "middle"
143
- }
144
- }])
145
- .accessors({ x: (d2: any) => d2.x, y: (d2: any) => d2.y });
146
- this._tooltipG.call(annotationtip as any);
147
- }
148
- }
149
-
150
- protected calcSize(textElement, width: number, height: number): { width: number, height: number, scale: number } {
151
- const bb = (textElement.node() as any).getBBox();
152
- const widthTransform = width / bb.width;
153
- const heightTransform = height / bb.height;
154
- const scale = widthTransform < heightTransform ? widthTransform : heightTransform;
155
- return {
156
- width: bb.width,
157
- height: bb.height,
158
- scale
159
- };
160
- }
161
-
162
- protected updateText(textElement, x: number, y: number, w: number, h: number) {
163
- textElement
164
- .datum({ x, y, w, h })
165
- .attr("transform", null)
166
- ;
167
- const size = this.calcSize(textElement, w, h);
168
- const x2 = x + w / 2 - size.width / 2 * size.scale;
169
- const y2 = y + h / 2 - size.height / 2 * size.scale;
170
- textElement.attr("transform", `translate(${x2}, ${y2}) scale(${size.scale})`);
171
- }
172
-
173
- calcWidth(): number {
174
- return Math.min(this.width(), this.height(), this.maxDiameter());
175
- }
176
-
177
- enter(domNode: HTMLElement, element) {
178
- super.enter(domNode, element);
179
-
180
- element.on("click", (d: Gauge) => {
181
- this.click(d);
182
- });
183
-
184
- this._usageArc = element.append("path").datum({ startAngle: value2Angle(0), endAngle: value2Angle(0) })
185
- .style("fill", "green")
186
- .on("mousemove", (d: any) => {
187
- const [x, y] = this._d3Arc.centroid(d);
188
- this.tip({ x, y, label: this.valueDescription() });
189
- })
190
- .on("mouseout", (d: any) => {
191
- this.tip(null);
192
- })
193
- ;
194
- this._freeArc = element.append("path").datum({ startAngle: value2Angle(0), endAngle: value2Angle(1) })
195
- .style("fill", "lightGrey")
196
- ;
197
- this._meanArc = element.append("path").datum({ startAngle: value2Angle(0), endAngle: value2Angle(0) })
198
- .style("fill", "black")
199
- .on("mousemove", (d: any) => {
200
- const [x, y] = this._d3Arc.centroid(d);
201
- this.tip({ x, y, label: this.tickValueDescription() });
202
- })
203
- .on("mouseout", (d: any) => {
204
- this.tip(null);
205
- })
206
- ;
207
-
208
- this._mainTooltip = element.append("title");
209
-
210
- const context = this;
211
- function appendIndicator() {
212
- return element.append("path").datum({ angle: value2Angle(0) })
213
- .style("fill", "black")
214
- .style("stroke", "black")
215
- .attr("d", "M 0 0 l -3 -3 l 6 0 z")
216
- .on("mousemove", (d: any) => {
217
- const [x, y] = context._d3Arc.centroid(context._meanArc.datum() as any);
218
- context.tip({ x, y, label: context.tickValueDescription() });
219
- })
220
- .on("mouseout", (d: any) => {
221
- context.tip(null);
222
- })
223
- ;
224
- }
225
- this._indInner = appendIndicator();
226
- this._indOuter = appendIndicator();
227
- this._centerText = element.append("text")
228
- .attr("dy", ".66em")
229
- .style("fill", "green")
230
- .on("mousemove", (d: any) => {
231
- this.tip({ x: 0, y: 0, label: this.valueDescription() });
232
- })
233
- .on("mouseout", (d: any) => {
234
- this.tip(null);
235
- })
236
- ;
237
- this._bottomText = element.append("text")
238
- .attr("dy", ".66em")
239
- .on("mousemove", (d: any) => {
240
- this.tip({ x: 0, y: d.y, label: this.titleDescription() });
241
- })
242
- .on("mouseout", (d: any) => {
243
- this.tip(null);
244
- })
245
- ;
246
-
247
- this._tooltipG = element.append("g")
248
- .attr("class", "annotation-tip")
249
- ;
250
- }
251
-
252
- update(domNode: HTMLElement, element) {
253
- super.update(domNode, element);
254
-
255
- this._colorScale
256
- .domain(this.colorDomain())
257
- .range(this.colorRange())
258
- ;
259
- element
260
- .attr("title", this.tooltip())
261
- .style("cursor", this.click !== Gauge.prototype.click ? "pointer" : null)
262
- ;
263
-
264
- const innerRadius = this.calcWidth() / 3;
265
- const outerRadius = this.calcWidth() / 2 - 5;
266
- this._d3Arc
267
- .innerRadius(innerRadius)
268
- .outerRadius(outerRadius)
269
- ;
270
-
271
- const val = this.value();
272
- const tickVal = this.tickValue();
273
-
274
- this._usageArc
275
- .style("fill", this._colorScale(val))
276
- .transition()
277
- .duration(750)
278
- .attrTween("d", arcTween(value2Angle(0), value2Angle(val), this._d3Arc))
279
- ;
280
-
281
- this._freeArc
282
- .style("fill", this.emptyColor())
283
- .transition()
284
- .duration(750)
285
- .attrTween("d", arcTween(value2Angle(val), value2Angle(1), this._d3Arc))
286
- ;
287
-
288
- this._meanArc
289
- .style("fill", this.tickColor())
290
- .style("visibility", this.showTick() ? "visible" : "hidden")
291
- .transition()
292
- .duration(750)
293
- .attrTween("d", arcTween(value2Angle(tickVal - 0.001), value2Angle(tickVal + 0.001), this._d3Arc))
294
- ;
295
-
296
- this._indInner
297
- .style("fill", this.tickColor())
298
- .style("stroke", this.tickColor())
299
- .style("visibility", this.showTick() ? "visible" : "hidden")
300
- .transition()
301
- .duration(750)
302
- .attrTween("transform", indicatorTween(value2Angle(tickVal), innerRadius, true))
303
- ;
304
-
305
- this._indOuter
306
- .style("fill", this.tickColor())
307
- .style("stroke", this.tickColor())
308
- .style("visibility", this.showTick() ? "visible" : "hidden")
309
- .transition()
310
- .duration(750)
311
- .attrTween("transform", indicatorTween(value2Angle(tickVal), outerRadius))
312
- ;
313
-
314
- this._centerText
315
- .style("fill", this._colorScale(val))
316
- .text(d3Format(".0%")(val))
317
- ;
318
-
319
- this._bottomText
320
- .style("fill", this.click !== Gauge.prototype.click ? "blue" : "black")
321
- .style("text-decoration", this.click !== Gauge.prototype.click ? "underline" : null)
322
- .text(this.title())
323
- ;
324
-
325
- // Update Text ---
326
- const point = pointOnArc(value2Angle(1), innerRadius - 8);
327
- this.updateText(this._centerText, -point.x, -point.y, 2 * point.x, 2 * point.y);
328
-
329
- const point2 = pointOnArc(value2Angle(1), outerRadius);
330
- point2.y += 5;
331
- const width = this.calcWidth() - 20;
332
- const height = this.calcWidth() / 2 - point2.y - 5;
333
- this.updateText(this._bottomText, -width / 2, point2.y, width, height);
334
-
335
- this._mainTooltip.text(this.tooltip());
336
- }
337
-
338
- // Events ---
339
- click(w: Gauge) {
340
- }
341
- }
342
- Gauge.prototype._class += " chart_Gauge";
343
-
344
- export interface Gauge {
345
- tickColor(): string;
346
- tickColor(_: string): this;
347
- emptyColor(): string;
348
- emptyColor(_: string): this;
349
- colorDomain(): number[];
350
- colorDomain(_: number[]): this;
351
- colorRange(): string[];
352
- colorRange(_: string[]): this;
353
- }
354
-
355
- Gauge.prototype.publish("colorRange", ["green", "green", "green", "green", "green", "green", "green", "green", "orange", "red", "red"], "array", "Array of colors for the filled gauge portion. The fill color will be relative to the gauge value.");
356
- Gauge.prototype.publish("colorDomain", [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], "array", "This array augments the mapping of the value to the fill colorRange.");
357
- Gauge.prototype.publish("emptyColor", "lightgrey", "html-color", "Color of the empty portion of the gauge");
358
- Gauge.prototype.publish("tickColor", "black", "html-color", "Color of the tick");
1
+ import { publish, SVGWidget } from "@hpcc-js/common";
2
+ import { format as d3Format } from "d3-format";
3
+ import { interpolate as d3Interpolate, interpolateHcl as d3InterpolateHcl } from "d3-interpolate";
4
+ import { scaleLinear } from "d3-scale";
5
+ import { Arc, arc as d3Arc, DefaultArcObject } from "d3-shape";
6
+ import { annotation as d3Annotation, annotationCalloutElbow } from "d3-svg-annotation";
7
+
8
+ function value2Angle(value: number): number {
9
+ return (value - 0.5) * .65 * 2 * Math.PI;
10
+ }
11
+
12
+ function pointOnArc(angle: number, radius: number): { x: number, y: number } {
13
+ return {
14
+ x: Math.cos(angle - Math.PI / 2) * radius,
15
+ y: Math.sin(angle - Math.PI / 2) * radius
16
+ };
17
+ }
18
+
19
+ function indicatorTranslate(angle: number, radius: number, inner: boolean = false) {
20
+ const point = pointOnArc(angle, radius);
21
+ const rotation = angle * 180 / Math.PI + (inner === true ? 180 : 0);
22
+ return `translate(${point.x}, ${point.y}) rotate(${rotation})`;
23
+ }
24
+
25
+ type IndicatorDatum = { angle: number };
26
+ function indicatorTween(newAngle: number, radius: number, inner: boolean = false) {
27
+ return function (d: IndicatorDatum) {
28
+ const interpolate = d3Interpolate(d.angle, newAngle);
29
+ d.angle = newAngle;
30
+ return function (t: number) {
31
+ return indicatorTranslate(interpolate(t), radius, inner);
32
+ };
33
+ };
34
+ }
35
+
36
+ function arcTween(startAngle: number, endAngle: number, arc: Arc<any, DefaultArcObject>) {
37
+ return function (d: DefaultArcObject) {
38
+ const startInterpolate = d3Interpolate(d.startAngle, startAngle);
39
+ const endInterpolate = d3Interpolate(d.endAngle, endAngle);
40
+ return function (t: number): string {
41
+ d.startAngle = startInterpolate(t);
42
+ d.endAngle = endInterpolate(t);
43
+ return arc(d)!;
44
+ };
45
+ };
46
+ }
47
+
48
+ export class Gauge extends SVGWidget {
49
+
50
+ private _d3Arc: Arc<any, DefaultArcObject> = d3Arc()
51
+ .innerRadius(85)
52
+ .outerRadius(100)
53
+ ;
54
+ private _colorScale = scaleLinear<string, string>()
55
+ .interpolate(d3InterpolateHcl)
56
+ ;
57
+
58
+ protected _usageArc: any;
59
+ protected _meanArc: any;
60
+ protected _freeArc: any;
61
+ protected _indInner: any;
62
+ protected _indOuter: any;
63
+ protected _centerTextG: any;
64
+ protected _centerText: any;
65
+ protected _bottomText: any;
66
+ protected _tooltipG: any;
67
+ protected _mainTooltip: any;
68
+
69
+ @publish("", "string")
70
+ title: publish<this, string>;
71
+
72
+ @publish("", "string")
73
+ titleDescription: publish<this, string>;
74
+
75
+ @publish(128, "number")
76
+ maxDiameter: publish<this, number>;
77
+
78
+ @publish(0, "number")
79
+ value: publish<this, number>;
80
+
81
+ @publish("", "string")
82
+ valueDescription: publish<this, string>;
83
+
84
+ @publish(false, "boolean")
85
+ showTick: publish<this, boolean>;
86
+
87
+ @publish(0, "number")
88
+ tickValue: publish<this, number>;
89
+
90
+ @publish("", "string")
91
+ tickValueDescription: publish<this, string>;
92
+
93
+ @publish("", "string")
94
+ tooltip: publish<this, string>;
95
+
96
+ constructor() {
97
+ super();
98
+ }
99
+
100
+ protected tip(d: any) {
101
+ if (d === null || d.label === "") {
102
+ this._tooltipG
103
+ .transition()
104
+ .style("opacity", 0)
105
+ .on("interrupt end", () => {
106
+ this._tooltipG
107
+ .selectAll("g")
108
+ .remove()
109
+ ;
110
+ })
111
+ ;
112
+ } else {
113
+ this._tooltipG
114
+ .interrupt()
115
+ .style("opacity", 1)
116
+ ;
117
+ d.w = (this._centerText.datum() as any).w + 10;
118
+ let lineType = "horizontal";
119
+ let xOffset = 0;
120
+ let yOffset = 5;
121
+ let padding: number | undefined = 5;
122
+ if (d.y >= 5 && d.y <= 25) {
123
+ xOffset = d.x < 0 ? -d.w / 2 : d.w / 2;
124
+ yOffset = 12.5;
125
+ padding = undefined;
126
+ lineType = "vertical";
127
+ } else if (d.y > 25) {
128
+ yOffset = 25;
129
+ padding = 0;
130
+ }
131
+ const annotationtip = d3Annotation()
132
+ .type(annotationCalloutElbow)
133
+ .annotations([{
134
+ data: d,
135
+ dx: -d.x + xOffset,
136
+ dy: -d.y + yOffset,
137
+ color: "black",
138
+ note: {
139
+ label: d.label,
140
+ lineType,
141
+ padding,
142
+ align: "middle"
143
+ }
144
+ }])
145
+ .accessors({ x: (d2: any) => d2.x, y: (d2: any) => d2.y });
146
+ this._tooltipG.call(annotationtip as any);
147
+ }
148
+ }
149
+
150
+ protected calcSize(textElement, width: number, height: number): { width: number, height: number, scale: number } {
151
+ const bb = (textElement.node() as any).getBBox();
152
+ const widthTransform = width / bb.width;
153
+ const heightTransform = height / bb.height;
154
+ const scale = widthTransform < heightTransform ? widthTransform : heightTransform;
155
+ return {
156
+ width: bb.width,
157
+ height: bb.height,
158
+ scale
159
+ };
160
+ }
161
+
162
+ protected updateText(textElement, x: number, y: number, w: number, h: number) {
163
+ textElement
164
+ .datum({ x, y, w, h })
165
+ .attr("transform", null)
166
+ ;
167
+ const size = this.calcSize(textElement, w, h);
168
+ const x2 = x + w / 2 - size.width / 2 * size.scale;
169
+ const y2 = y + h / 2 - size.height / 2 * size.scale;
170
+ textElement.attr("transform", `translate(${x2}, ${y2}) scale(${size.scale})`);
171
+ }
172
+
173
+ calcWidth(): number {
174
+ return Math.min(this.width(), this.height(), this.maxDiameter());
175
+ }
176
+
177
+ enter(domNode: HTMLElement, element) {
178
+ super.enter(domNode, element);
179
+
180
+ element.on("click", (d: Gauge) => {
181
+ this.click(d);
182
+ });
183
+
184
+ this._usageArc = element.append("path").datum({ startAngle: value2Angle(0), endAngle: value2Angle(0) })
185
+ .style("fill", "green")
186
+ .on("mousemove", (d: any) => {
187
+ const [x, y] = this._d3Arc.centroid(d);
188
+ this.tip({ x, y, label: this.valueDescription() });
189
+ })
190
+ .on("mouseout", (d: any) => {
191
+ this.tip(null);
192
+ })
193
+ ;
194
+ this._freeArc = element.append("path").datum({ startAngle: value2Angle(0), endAngle: value2Angle(1) })
195
+ .style("fill", "lightGrey")
196
+ ;
197
+ this._meanArc = element.append("path").datum({ startAngle: value2Angle(0), endAngle: value2Angle(0) })
198
+ .style("fill", "black")
199
+ .on("mousemove", (d: any) => {
200
+ const [x, y] = this._d3Arc.centroid(d);
201
+ this.tip({ x, y, label: this.tickValueDescription() });
202
+ })
203
+ .on("mouseout", (d: any) => {
204
+ this.tip(null);
205
+ })
206
+ ;
207
+
208
+ this._mainTooltip = element.append("title");
209
+
210
+ const context = this;
211
+ function appendIndicator() {
212
+ return element.append("path").datum({ angle: value2Angle(0) })
213
+ .style("fill", "black")
214
+ .style("stroke", "black")
215
+ .attr("d", "M 0 0 l -3 -3 l 6 0 z")
216
+ .on("mousemove", (d: any) => {
217
+ const [x, y] = context._d3Arc.centroid(context._meanArc.datum() as any);
218
+ context.tip({ x, y, label: context.tickValueDescription() });
219
+ })
220
+ .on("mouseout", (d: any) => {
221
+ context.tip(null);
222
+ })
223
+ ;
224
+ }
225
+ this._indInner = appendIndicator();
226
+ this._indOuter = appendIndicator();
227
+ this._centerText = element.append("text")
228
+ .attr("dy", ".66em")
229
+ .style("fill", "green")
230
+ .on("mousemove", (d: any) => {
231
+ this.tip({ x: 0, y: 0, label: this.valueDescription() });
232
+ })
233
+ .on("mouseout", (d: any) => {
234
+ this.tip(null);
235
+ })
236
+ ;
237
+ this._bottomText = element.append("text")
238
+ .attr("dy", ".66em")
239
+ .on("mousemove", (d: any) => {
240
+ this.tip({ x: 0, y: d.y, label: this.titleDescription() });
241
+ })
242
+ .on("mouseout", (d: any) => {
243
+ this.tip(null);
244
+ })
245
+ ;
246
+
247
+ this._tooltipG = element.append("g")
248
+ .attr("class", "annotation-tip")
249
+ ;
250
+ }
251
+
252
+ update(domNode: HTMLElement, element) {
253
+ super.update(domNode, element);
254
+
255
+ this._colorScale
256
+ .domain(this.colorDomain())
257
+ .range(this.colorRange())
258
+ ;
259
+ element
260
+ .attr("title", this.tooltip())
261
+ .style("cursor", this.click !== Gauge.prototype.click ? "pointer" : null)
262
+ ;
263
+
264
+ const innerRadius = this.calcWidth() / 3;
265
+ const outerRadius = this.calcWidth() / 2 - 5;
266
+ this._d3Arc
267
+ .innerRadius(innerRadius)
268
+ .outerRadius(outerRadius)
269
+ ;
270
+
271
+ const val = this.value();
272
+ const tickVal = this.tickValue();
273
+
274
+ this._usageArc
275
+ .style("fill", this._colorScale(val))
276
+ .transition()
277
+ .duration(750)
278
+ .attrTween("d", arcTween(value2Angle(0), value2Angle(val), this._d3Arc))
279
+ ;
280
+
281
+ this._freeArc
282
+ .style("fill", this.emptyColor())
283
+ .transition()
284
+ .duration(750)
285
+ .attrTween("d", arcTween(value2Angle(val), value2Angle(1), this._d3Arc))
286
+ ;
287
+
288
+ this._meanArc
289
+ .style("fill", this.tickColor())
290
+ .style("visibility", this.showTick() ? "visible" : "hidden")
291
+ .transition()
292
+ .duration(750)
293
+ .attrTween("d", arcTween(value2Angle(tickVal - 0.001), value2Angle(tickVal + 0.001), this._d3Arc))
294
+ ;
295
+
296
+ this._indInner
297
+ .style("fill", this.tickColor())
298
+ .style("stroke", this.tickColor())
299
+ .style("visibility", this.showTick() ? "visible" : "hidden")
300
+ .transition()
301
+ .duration(750)
302
+ .attrTween("transform", indicatorTween(value2Angle(tickVal), innerRadius, true))
303
+ ;
304
+
305
+ this._indOuter
306
+ .style("fill", this.tickColor())
307
+ .style("stroke", this.tickColor())
308
+ .style("visibility", this.showTick() ? "visible" : "hidden")
309
+ .transition()
310
+ .duration(750)
311
+ .attrTween("transform", indicatorTween(value2Angle(tickVal), outerRadius))
312
+ ;
313
+
314
+ this._centerText
315
+ .style("fill", this._colorScale(val))
316
+ .text(d3Format(".0%")(val))
317
+ ;
318
+
319
+ this._bottomText
320
+ .style("fill", this.click !== Gauge.prototype.click ? "blue" : "black")
321
+ .style("text-decoration", this.click !== Gauge.prototype.click ? "underline" : null)
322
+ .text(this.title())
323
+ ;
324
+
325
+ // Update Text ---
326
+ const point = pointOnArc(value2Angle(1), innerRadius - 8);
327
+ this.updateText(this._centerText, -point.x, -point.y, 2 * point.x, 2 * point.y);
328
+
329
+ const point2 = pointOnArc(value2Angle(1), outerRadius);
330
+ point2.y += 5;
331
+ const width = this.calcWidth() - 20;
332
+ const height = this.calcWidth() / 2 - point2.y - 5;
333
+ this.updateText(this._bottomText, -width / 2, point2.y, width, height);
334
+
335
+ this._mainTooltip.text(this.tooltip());
336
+ }
337
+
338
+ // Events ---
339
+ click(w: Gauge) {
340
+ }
341
+ }
342
+ Gauge.prototype._class += " chart_Gauge";
343
+
344
+ export interface Gauge {
345
+ tickColor(): string;
346
+ tickColor(_: string): this;
347
+ emptyColor(): string;
348
+ emptyColor(_: string): this;
349
+ colorDomain(): number[];
350
+ colorDomain(_: number[]): this;
351
+ colorRange(): string[];
352
+ colorRange(_: string[]): this;
353
+ }
354
+
355
+ Gauge.prototype.publish("colorRange", ["green", "green", "green", "green", "green", "green", "green", "green", "orange", "red", "red"], "array", "Array of colors for the filled gauge portion. The fill color will be relative to the gauge value.");
356
+ Gauge.prototype.publish("colorDomain", [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1], "array", "This array augments the mapping of the value to the fill colorRange.");
357
+ Gauge.prototype.publish("emptyColor", "lightgrey", "html-color", "Color of the empty portion of the gauge");
358
+ Gauge.prototype.publish("tickColor", "black", "html-color", "Color of the tick");