@hpcc-js/chart 3.7.1 → 3.7.4

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