@hpcc-js/chart 2.86.2 → 2.86.3

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 (78) hide show
  1. package/LICENSE +43 -43
  2. package/README.md +93 -93
  3. package/dist/index.es6.js.map +1 -1
  4. package/dist/index.js.map +1 -1
  5. package/dist/index.min.js.map +1 -1
  6. package/package.json +6 -6
  7. package/src/Area.md +176 -176
  8. package/src/Area.ts +12 -12
  9. package/src/Axis.css +34 -34
  10. package/src/Axis.ts +733 -733
  11. package/src/Bar.md +90 -90
  12. package/src/Bar.ts +9 -9
  13. package/src/Bubble.css +16 -16
  14. package/src/Bubble.md +69 -69
  15. package/src/Bubble.ts +191 -191
  16. package/src/BubbleXY.ts +14 -14
  17. package/src/Bullet.css +60 -60
  18. package/src/Bullet.md +104 -104
  19. package/src/Bullet.ts +167 -167
  20. package/src/Column.css +17 -17
  21. package/src/Column.md +90 -90
  22. package/src/Column.ts +659 -659
  23. package/src/Contour.md +88 -88
  24. package/src/Contour.ts +97 -97
  25. package/src/D3Cloud.ts +400 -400
  26. package/src/Gantt.md +119 -119
  27. package/src/Gantt.ts +14 -14
  28. package/src/Gauge.md +148 -148
  29. package/src/Gauge.ts +358 -358
  30. package/src/HalfPie.md +62 -62
  31. package/src/HalfPie.ts +26 -26
  32. package/src/Heat.md +42 -42
  33. package/src/Heat.ts +283 -283
  34. package/src/HexBin.css +9 -9
  35. package/src/HexBin.md +88 -88
  36. package/src/HexBin.ts +139 -139
  37. package/src/Line.css +6 -6
  38. package/src/Line.md +170 -170
  39. package/src/Line.ts +14 -14
  40. package/src/Pie.css +23 -23
  41. package/src/Pie.md +88 -88
  42. package/src/Pie.ts +503 -503
  43. package/src/QuarterPie.md +61 -61
  44. package/src/QuarterPie.ts +35 -35
  45. package/src/QuartileCandlestick.md +129 -129
  46. package/src/QuartileCandlestick.ts +349 -349
  47. package/src/Radar.css +15 -15
  48. package/src/Radar.md +104 -104
  49. package/src/Radar.ts +336 -336
  50. package/src/RadialBar.css +25 -25
  51. package/src/RadialBar.md +91 -91
  52. package/src/RadialBar.ts +212 -212
  53. package/src/Scatter.css +16 -16
  54. package/src/Scatter.md +163 -163
  55. package/src/Scatter.ts +376 -376
  56. package/src/StatChart.md +117 -117
  57. package/src/StatChart.ts +253 -253
  58. package/src/Step.md +163 -163
  59. package/src/Step.ts +12 -12
  60. package/src/Summary.css +56 -56
  61. package/src/Summary.md +219 -219
  62. package/src/Summary.ts +322 -322
  63. package/src/SummaryC.md +154 -154
  64. package/src/SummaryC.ts +240 -240
  65. package/src/WordCloud.css +3 -3
  66. package/src/WordCloud.md +144 -144
  67. package/src/WordCloud.ts +263 -263
  68. package/src/XYAxis.css +41 -41
  69. package/src/XYAxis.md +149 -149
  70. package/src/XYAxis.ts +803 -803
  71. package/src/__package__.ts +3 -3
  72. package/src/__tests__/heat.ts +71 -71
  73. package/src/__tests__/index.ts +3 -3
  74. package/src/__tests__/pie.ts +20 -20
  75. package/src/__tests__/stat.ts +16 -16
  76. package/src/__tests__/test3.ts +69 -69
  77. package/src/index.ts +27 -27
  78. package/src/test.ts +71 -71
package/src/Scatter.ts CHANGED
@@ -1,376 +1,376 @@
1
- import { INDChart, ITooltip } from "@hpcc-js/api";
2
- import { InputField } from "@hpcc-js/common";
3
- import { extent as d3Extent } from "d3-array";
4
- import { scaleLinear as d3ScaleLinear, scaleLog as d3ScaleLog, scalePow as d3ScalePow, scaleSqrt as d3ScaleSqrt } from "d3-scale";
5
- import { select as d3Select } from "d3-selection";
6
- import {
7
- area as d3Area,
8
- curveBasis as d3CurveBasis, curveBundle as d3CurveBundle, curveCardinal as d3CurveCardinal, curveCatmullRom as d3curveCatmullRom, curveLinear as d3CurveLinear,
9
- curveMonotoneX as d3CurveMonotoneX, curveNatural as d3CurveNatural, curveStep as d3CurveStep, curveStepAfter as d3CurveStepAfter, curveStepBefore as d3CurveStepBefore,
10
- line as d3Line
11
- } from "d3-shape";
12
- import { XYAxis } from "./XYAxis";
13
-
14
- import "../src/Scatter.css";
15
-
16
- export class Scatter extends XYAxis {
17
- static __inputs: InputField[] = [{
18
- id: "label",
19
- type: "any"
20
- }, {
21
- id: "values",
22
- type: "number",
23
- multi: true
24
- }];
25
-
26
- constructor() {
27
- super();
28
- INDChart.call(this);
29
- ITooltip.call(this);
30
- this
31
- .xAxisGuideLines_default(true)
32
- .yAxisGuideLines_default(true)
33
- ;
34
- }
35
-
36
- xPos(host: XYAxis, d) {
37
- return host.orientation() === "horizontal" ? host.dataPos(d.label) : host.valuePos(d.value);
38
- }
39
-
40
- yPos(host: XYAxis, d) {
41
- return host.orientation() === "horizontal" ? host.valuePos(d.value) : host.dataPos(d.label);
42
- }
43
-
44
- private curve(): any {
45
- switch (this.interpolate()) {
46
- case "linear":
47
- return d3CurveLinear;
48
- case "step":
49
- return d3CurveStep;
50
- case "step-before":
51
- return d3CurveStepBefore;
52
- case "step-after":
53
- return d3CurveStepAfter;
54
- case "basis":
55
- return d3CurveBasis;
56
- case "bundle":
57
- return d3CurveBundle;
58
- case "cardinal":
59
- return d3CurveCardinal;
60
- case "catmullRom":
61
- return d3curveCatmullRom;
62
- case "natural":
63
- return d3CurveNatural;
64
- case "monotone":
65
- default:
66
- return d3CurveMonotoneX;
67
- }
68
- }
69
-
70
- private getScale() {
71
- switch (this.pointSizeScale()) {
72
- case "linear":
73
- return d3ScaleLinear();
74
- case "pow":
75
- return d3ScalePow().exponent(2);
76
- case "log":
77
- return d3ScaleLog();
78
- case "sqrt":
79
- return d3ScaleSqrt();
80
- }
81
- }
82
-
83
- protected pointColor(row, col, value, origRow) {
84
- if (this.interpolate() && this.pointDarken()) {
85
- return this.strokeColor(row, col, value, origRow);
86
- }
87
- return this.fillColor(row, col, value, origRow);
88
- }
89
-
90
- protected lineColor(row, col, value, origRow) {
91
- if (this.interpolateFill() && this.interpolateDarken()) {
92
- return this.strokeColor(row, col, value, origRow);
93
- }
94
- return this.fillColor(row, col, value, origRow);
95
- }
96
-
97
- protected areaColor(row, col, value, origRow) {
98
- return this.fillColor(row, col, value, origRow);
99
- }
100
-
101
- layerEnter(host: XYAxis, element, duration: number = 250) {
102
- super.layerEnter(host, element, duration);
103
- const context = this;
104
- this
105
- .tooltipHTML(function (d) {
106
- switch (context.tooltipStyle()) {
107
- case "series-table":
108
- return context.tooltipFormat({
109
- label: d.label,
110
- arr: context.columns().slice(1).map(function (column, i) {
111
- return {
112
- label: column,
113
- color: context._palette(column),
114
- value: context.data()[d.rowIdx][i + 1]
115
- };
116
- })
117
- });
118
- default:
119
- return context.tooltipFormat({ label: d.label, series: d.column, value: d.value });
120
- }
121
- })
122
- ;
123
- }
124
-
125
- protected _prevPointShape;
126
- layerUpdate(host: XYAxis, element, duration: number = 250) {
127
- super.layerUpdate(host, element);
128
- const isHorizontal = host.orientation() === "horizontal";
129
- const height = isHorizontal ? this.height() : this.width();
130
- const context = this;
131
-
132
- this._palette = this._palette.switch(this.paletteID());
133
- if (this.useClonedPalette()) {
134
- this._palette = this._palette.cloneNotExists(this.paletteID() + "_" + this.id());
135
- }
136
-
137
- if (this._prevPointShape !== this.pointShape()) {
138
- element.selectAll(".data").remove();
139
- this._prevPointShape = this.pointShape();
140
- }
141
-
142
- function mapShape(shape) {
143
- switch (shape) {
144
- case "rectangle":
145
- return "rect";
146
- case "circle":
147
- return "circle";
148
- case "cross":
149
- return "path";
150
- default:
151
- }
152
- }
153
- const usePointSizeColumn = this.pointSizeColumn_exists();
154
- let pointSizeColumnIdx;
155
- let extent;
156
- let scale;
157
- if (usePointSizeColumn) {
158
- pointSizeColumnIdx = this.columns().indexOf(this.pointSizeColumn());
159
- extent = d3Extent(this.data(), d => d[pointSizeColumnIdx]);
160
- scale = this.getScale().domain(extent);
161
- }
162
- const layerColumns = this.layerColumns(host);
163
- const layerData = this.layerData(host);
164
- const flatData = this.flattenData(layerColumns, layerData).map(function (d) {
165
- d.shape = mapShape(context.pointShape());
166
- d.column = layerColumns[d.colIdx];
167
- d.row = layerData[d.rowIdx];
168
- d.origRow = (layerData[d.rowIdx] as any).__hpcc_origRow;
169
- if (extent) {
170
- d.size = scale(d.row[pointSizeColumnIdx]) * (context.maxPointSize() - context.minPointSize()) + context.minPointSize();
171
- return d.column === context.pointSizeColumn() ? false : d;
172
- } else {
173
- d.size = context.pointSize();
174
- return d;
175
- }
176
-
177
- }).filter(d => d);
178
-
179
- const areas = element.selectAll(".area").data(layerColumns.filter(function (_d, idx) { return context.interpolate() && context.interpolateFill() && idx > 0; }));
180
- const areasEnter = areas.enter().append("path");
181
- const area = d3Area()
182
- .curve(this.curve())
183
- ;
184
- if (isHorizontal) {
185
- area
186
- .x(function (d) { return context.xPos(host, d); })
187
- .y0(Math.min(height, this.yPos(host, { value: 0 })))
188
- .y1(function (d) { return context.yPos(host, d); })
189
- ;
190
- } else {
191
- area
192
- .y(function (d) { return context.yPos(host, d); })
193
- .x0(Math.max(0, this.xPos(host, { value: 0 })))
194
- .x1(function (d) { return context.xPos(host, d); })
195
- ;
196
- }
197
- areasEnter.merge(areas)
198
- .attr("class", d => "area series series-" + this.cssTag(d))
199
- .each(function (_d, idx) {
200
- const element = d3Select(this);
201
- element
202
- .attr("d", area(flatData.filter(function (d2) { return d2.colIdx === idx + 1; })))
203
- .style("opacity", context.interpolateFillOpacity())
204
- .style("stroke", "none")
205
- .style("fill", context.areaColor([], _d, undefined, []))
206
- ;
207
- });
208
- areas.exit().remove();
209
-
210
- const lines = element.selectAll(".line").data(layerColumns.filter(function (_d, idx) { return context.interpolate() && idx > 0; }));
211
- const linesEnter = lines.enter().append("path");
212
- const line = d3Line()
213
- .x(function (d) { return context.xPos(host, d); })
214
- .y(function (d) { return context.yPos(host, d); })
215
- .curve(this.curve())
216
- ;
217
- linesEnter.merge(lines)
218
- .attr("class", d => "line series series-" + this.cssTag(d))
219
- .each(function (_d, idx) {
220
- const element = d3Select(this);
221
- const data2 = flatData.filter(function (d2) { return d2.colIdx === idx + 1; });
222
- element
223
- .attr("d", line(data2))
224
- .style("stroke", context.lineColor([], _d, undefined, []))
225
- .style("fill", "none")
226
- ;
227
- });
228
- lines.exit().remove();
229
-
230
- const points = element.selectAll(".point").data(flatData, function (d, idx) { return d.shape + "_" + idx; });
231
- points.enter().append("g")
232
- .each(function (this: SVGElement, d2) {
233
- const element = d3Select(this);
234
- element
235
- .append(d2.shape)
236
- .attr("class", "pointShape")
237
- ;
238
- element
239
- .append("text")
240
- .attr("class", "pointValue")
241
- .style("display", "none")
242
- .attr("text-anchor", context.valueAnchor())
243
- .attr("alignment-baseline", context.valueBaseline())
244
- .attr("fill", function (d: any, _idx) {
245
- const useTextColor = context.valueBaseline() === "middle" || context.valueBaseline() === "central";
246
- return useTextColor ? context.textColor(d.row, d.column, d.value, d.origRow) : null;
247
- })
248
- ;
249
- element
250
- .append("circle")
251
- .attr("class", "pointSelection")
252
- .on("mouseout.tooltip", context.tooltip.hide)
253
- .on("mousemove.tooltip", context.tooltip.show)
254
- .call(host._selection.enter.bind(host._selection))
255
- .on("click", function (d: any, _idx) {
256
- context.click(host.rowToObj(host.data()[d.rowIdx]), d.column, host._selection.selected(this));
257
- })
258
- .on("dblclick", function (d: any, _idx) {
259
- context.dblclick(host.rowToObj(host.data()[d.rowIdx]), d.column, host._selection.selected(this));
260
- })
261
- ;
262
- })
263
- .merge(points)
264
- .attr("class", d => "point series series-" + this.cssTag(d.column))
265
- .each(function (this: SVGElement, d2) {
266
- const textSelection = d3Select(this).select(".pointValue");
267
- textSelection
268
- .attr("x", function (d) { return context.xPos(host, d); })
269
- .attr("y", function (d) { return context.yPos(host, d); })
270
- .style("display", context.showValue() ? "block" : "none")
271
- .attr("text-anchor", context.valueAnchor())
272
- .attr("alignment-baseline", context.valueBaseline())
273
- .text(function (d) {
274
- return d["value"];
275
- })
276
- ;
277
- const elementSelection = d3Select(this).select(".pointSelection");
278
- elementSelection
279
- .attr("cx", function (d) { return context.xPos(host, d); })
280
- .attr("cy", function (d) { return context.yPos(host, d); })
281
- .attr("r", d2.size)
282
- ;
283
-
284
- const element = d3Select(this).select(".pointShape");
285
- switch (d2.shape) {
286
- case "rect":
287
- element
288
- .attr("x", function (d) { return context.xPos(host, d) - d2.size / 2; })
289
- .attr("y", function (d) { return context.yPos(host, d) - d2.size / 2; })
290
- .attr("width", d2.size)
291
- .attr("height", d2.size)
292
- .style("fill", context.pointColor(d2.row, d2.column, d2.value, d2.origRow))
293
- ;
294
- break;
295
- case "circle":
296
- element
297
- .attr("cx", function (d) { return context.xPos(host, d); })
298
- .attr("cy", function (d) { return context.yPos(host, d); })
299
- .attr("r", d2.size * 0.9)
300
- .style("fill", context.pointColor(d2.row, d2.column, d2.value, d2.origRow))
301
- ;
302
- break;
303
- case "path":
304
- element
305
- .attr("d", function (d: any) {
306
- return "M" + (context.xPos(host, d) - d2.size / 2) + " " + (context.yPos(host, d) - d2.size / 2) + " " +
307
- "L" + (context.xPos(host, d) + d2.size / 2) + " " + (context.yPos(host, d) + d2.size / 2) + " " +
308
- "M" + (context.xPos(host, d) - d2.size / 2) + " " + (context.yPos(host, d) + d2.size / 2) + " " +
309
- "L" + (context.xPos(host, d) + d2.size / 2) + " " + (context.yPos(host, d) - d2.size / 2);
310
- })
311
- .style("stroke", context.pointColor(d2.row, d2.column, d2.value, d2.origRow))
312
- ;
313
- break;
314
- default:
315
- }
316
- })
317
- ;
318
- points.exit().remove();
319
- }
320
-
321
- exit(domNode, element) {
322
- super.exit(domNode, element);
323
- }
324
-
325
- paletteID: { (): string; (_: string): Scatter; };
326
- useClonedPalette: { (): boolean; (_: boolean): Scatter; };
327
- pointSizeScale: { (): string; (_: string): Scatter; };
328
- pointShape: { (): string; (_: string): Scatter; };
329
- pointSize: { (): number; (_: number): Scatter; };
330
- interpolate: { (): string; (_: string): Scatter; };
331
- interpolate_default: { (): string; (_: string): Scatter; };
332
- interpolateFill: { (): boolean; (_: boolean): Scatter; };
333
- interpolateFill_default: { (): boolean; (_: boolean): Scatter; };
334
- interpolateFillOpacity: { (): number; (_: number): Scatter; };
335
-
336
- // INDChart
337
- _palette;
338
- fillColor: (row, column, value, origRow) => string;
339
- strokeColor: (row, column, value, origRow) => string;
340
- textColor: (row, column, value, origRow) => string;
341
- dblclick: (row, column, selected) => void;
342
-
343
- // ITooltip
344
- tooltip;
345
- tooltipHTML: (_) => string;
346
- tooltipFormat: (_) => string;
347
- tooltipStyle: () => "default" | "none" | "series-table";
348
- }
349
- Scatter.prototype._class += " chart_Scatter";
350
- Scatter.prototype.implements(INDChart.prototype);
351
- Scatter.prototype.implements(ITooltip.prototype);
352
- export interface Scatter {
353
- valueAnchor(): string;
354
- valueAnchor(_: string): this;
355
- valueBaseline(): string;
356
- valueBaseline(_: string): this;
357
- showValue(): boolean;
358
- showValue(_: boolean): this;
359
- pointDarken(): boolean;
360
- pointDarken(_: boolean): this;
361
- interpolateDarken(): boolean;
362
- interpolateDarken(_: boolean): this;
363
- }
364
- Scatter.prototype.publish("paletteID", "default", "set", "Color palette for this widget", Scatter.prototype._palette.switch(), { tags: ["Basic", "Shared"] });
365
- Scatter.prototype.publish("pointSizeScale", "linear", "set", "pointSizeScale", ["linear", "pow", "log", "sqrt"]);
366
- Scatter.prototype.publish("pointShape", "cross", "set", "Shape of the data points", ["circle", "rectangle", "cross"]);
367
- Scatter.prototype.publish("pointSize", 6, "number", "Point Size", null, { range: { min: 1, step: 1, max: 200 } });
368
- Scatter.prototype.publish("interpolate", "", "set", "Interpolate Data", ["", "linear", "step", "step-before", "step-after", "basis", "bundle", "cardinal", "catmullRom", "natural", "monotone"]);
369
- Scatter.prototype.publish("pointDarken", true, "boolean", "If true, and interpolate is set, then points will have a slightly darker color than their assigned palette color", null, { disable: w => !w.interpolate() });
370
- Scatter.prototype.publish("interpolateDarken", true, "boolean", "If true, and interpolateFill is true, then lines will have a slightly darker color than their assigned palette color", null, { disable: w => !w.interpolateFill() });
371
- Scatter.prototype.publish("interpolateFill", false, "boolean", "If true, the area between the line and zero will be filled");
372
- Scatter.prototype.publish("interpolateFillOpacity", 0.66, "number", "Fill interpolation Opacity", null, { range: { min: 0, step: 0.01, max: 1 } });
373
- Scatter.prototype.publish("useClonedPalette", false, "boolean", "Enable or disable using a cloned palette", null, { tags: ["Intermediate", "Shared"] });
374
- Scatter.prototype.publish("showValue", false, "boolean");
375
- Scatter.prototype.publish("valueAnchor", "middle", "set", "text-anchor for shown value text", ["start", "middle", "end"]);
376
- Scatter.prototype.publish("valueBaseline", "ideographic", "set", "alignment-baseline for shown value text", ["auto", "baseline", "before-edge", "text-before-edge", "middle", "central", "after-edge", "text-after-edge", "ideographic", "alphabetic", "hanging", "mathematical", "inherit"]);
1
+ import { INDChart, ITooltip } from "@hpcc-js/api";
2
+ import { InputField } from "@hpcc-js/common";
3
+ import { extent as d3Extent } from "d3-array";
4
+ import { scaleLinear as d3ScaleLinear, scaleLog as d3ScaleLog, scalePow as d3ScalePow, scaleSqrt as d3ScaleSqrt } from "d3-scale";
5
+ import { select as d3Select } from "d3-selection";
6
+ import {
7
+ area as d3Area,
8
+ curveBasis as d3CurveBasis, curveBundle as d3CurveBundle, curveCardinal as d3CurveCardinal, curveCatmullRom as d3curveCatmullRom, curveLinear as d3CurveLinear,
9
+ curveMonotoneX as d3CurveMonotoneX, curveNatural as d3CurveNatural, curveStep as d3CurveStep, curveStepAfter as d3CurveStepAfter, curveStepBefore as d3CurveStepBefore,
10
+ line as d3Line
11
+ } from "d3-shape";
12
+ import { XYAxis } from "./XYAxis";
13
+
14
+ import "../src/Scatter.css";
15
+
16
+ export class Scatter extends XYAxis {
17
+ static __inputs: InputField[] = [{
18
+ id: "label",
19
+ type: "any"
20
+ }, {
21
+ id: "values",
22
+ type: "number",
23
+ multi: true
24
+ }];
25
+
26
+ constructor() {
27
+ super();
28
+ INDChart.call(this);
29
+ ITooltip.call(this);
30
+ this
31
+ .xAxisGuideLines_default(true)
32
+ .yAxisGuideLines_default(true)
33
+ ;
34
+ }
35
+
36
+ xPos(host: XYAxis, d) {
37
+ return host.orientation() === "horizontal" ? host.dataPos(d.label) : host.valuePos(d.value);
38
+ }
39
+
40
+ yPos(host: XYAxis, d) {
41
+ return host.orientation() === "horizontal" ? host.valuePos(d.value) : host.dataPos(d.label);
42
+ }
43
+
44
+ private curve(): any {
45
+ switch (this.interpolate()) {
46
+ case "linear":
47
+ return d3CurveLinear;
48
+ case "step":
49
+ return d3CurveStep;
50
+ case "step-before":
51
+ return d3CurveStepBefore;
52
+ case "step-after":
53
+ return d3CurveStepAfter;
54
+ case "basis":
55
+ return d3CurveBasis;
56
+ case "bundle":
57
+ return d3CurveBundle;
58
+ case "cardinal":
59
+ return d3CurveCardinal;
60
+ case "catmullRom":
61
+ return d3curveCatmullRom;
62
+ case "natural":
63
+ return d3CurveNatural;
64
+ case "monotone":
65
+ default:
66
+ return d3CurveMonotoneX;
67
+ }
68
+ }
69
+
70
+ private getScale() {
71
+ switch (this.pointSizeScale()) {
72
+ case "linear":
73
+ return d3ScaleLinear();
74
+ case "pow":
75
+ return d3ScalePow().exponent(2);
76
+ case "log":
77
+ return d3ScaleLog();
78
+ case "sqrt":
79
+ return d3ScaleSqrt();
80
+ }
81
+ }
82
+
83
+ protected pointColor(row, col, value, origRow) {
84
+ if (this.interpolate() && this.pointDarken()) {
85
+ return this.strokeColor(row, col, value, origRow);
86
+ }
87
+ return this.fillColor(row, col, value, origRow);
88
+ }
89
+
90
+ protected lineColor(row, col, value, origRow) {
91
+ if (this.interpolateFill() && this.interpolateDarken()) {
92
+ return this.strokeColor(row, col, value, origRow);
93
+ }
94
+ return this.fillColor(row, col, value, origRow);
95
+ }
96
+
97
+ protected areaColor(row, col, value, origRow) {
98
+ return this.fillColor(row, col, value, origRow);
99
+ }
100
+
101
+ layerEnter(host: XYAxis, element, duration: number = 250) {
102
+ super.layerEnter(host, element, duration);
103
+ const context = this;
104
+ this
105
+ .tooltipHTML(function (d) {
106
+ switch (context.tooltipStyle()) {
107
+ case "series-table":
108
+ return context.tooltipFormat({
109
+ label: d.label,
110
+ arr: context.columns().slice(1).map(function (column, i) {
111
+ return {
112
+ label: column,
113
+ color: context._palette(column),
114
+ value: context.data()[d.rowIdx][i + 1]
115
+ };
116
+ })
117
+ });
118
+ default:
119
+ return context.tooltipFormat({ label: d.label, series: d.column, value: d.value });
120
+ }
121
+ })
122
+ ;
123
+ }
124
+
125
+ protected _prevPointShape;
126
+ layerUpdate(host: XYAxis, element, duration: number = 250) {
127
+ super.layerUpdate(host, element);
128
+ const isHorizontal = host.orientation() === "horizontal";
129
+ const height = isHorizontal ? this.height() : this.width();
130
+ const context = this;
131
+
132
+ this._palette = this._palette.switch(this.paletteID());
133
+ if (this.useClonedPalette()) {
134
+ this._palette = this._palette.cloneNotExists(this.paletteID() + "_" + this.id());
135
+ }
136
+
137
+ if (this._prevPointShape !== this.pointShape()) {
138
+ element.selectAll(".data").remove();
139
+ this._prevPointShape = this.pointShape();
140
+ }
141
+
142
+ function mapShape(shape) {
143
+ switch (shape) {
144
+ case "rectangle":
145
+ return "rect";
146
+ case "circle":
147
+ return "circle";
148
+ case "cross":
149
+ return "path";
150
+ default:
151
+ }
152
+ }
153
+ const usePointSizeColumn = this.pointSizeColumn_exists();
154
+ let pointSizeColumnIdx;
155
+ let extent;
156
+ let scale;
157
+ if (usePointSizeColumn) {
158
+ pointSizeColumnIdx = this.columns().indexOf(this.pointSizeColumn());
159
+ extent = d3Extent(this.data(), d => d[pointSizeColumnIdx]);
160
+ scale = this.getScale().domain(extent);
161
+ }
162
+ const layerColumns = this.layerColumns(host);
163
+ const layerData = this.layerData(host);
164
+ const flatData = this.flattenData(layerColumns, layerData).map(function (d) {
165
+ d.shape = mapShape(context.pointShape());
166
+ d.column = layerColumns[d.colIdx];
167
+ d.row = layerData[d.rowIdx];
168
+ d.origRow = (layerData[d.rowIdx] as any).__hpcc_origRow;
169
+ if (extent) {
170
+ d.size = scale(d.row[pointSizeColumnIdx]) * (context.maxPointSize() - context.minPointSize()) + context.minPointSize();
171
+ return d.column === context.pointSizeColumn() ? false : d;
172
+ } else {
173
+ d.size = context.pointSize();
174
+ return d;
175
+ }
176
+
177
+ }).filter(d => d);
178
+
179
+ const areas = element.selectAll(".area").data(layerColumns.filter(function (_d, idx) { return context.interpolate() && context.interpolateFill() && idx > 0; }));
180
+ const areasEnter = areas.enter().append("path");
181
+ const area = d3Area()
182
+ .curve(this.curve())
183
+ ;
184
+ if (isHorizontal) {
185
+ area
186
+ .x(function (d) { return context.xPos(host, d); })
187
+ .y0(Math.min(height, this.yPos(host, { value: 0 })))
188
+ .y1(function (d) { return context.yPos(host, d); })
189
+ ;
190
+ } else {
191
+ area
192
+ .y(function (d) { return context.yPos(host, d); })
193
+ .x0(Math.max(0, this.xPos(host, { value: 0 })))
194
+ .x1(function (d) { return context.xPos(host, d); })
195
+ ;
196
+ }
197
+ areasEnter.merge(areas)
198
+ .attr("class", d => "area series series-" + this.cssTag(d))
199
+ .each(function (_d, idx) {
200
+ const element = d3Select(this);
201
+ element
202
+ .attr("d", area(flatData.filter(function (d2) { return d2.colIdx === idx + 1; })))
203
+ .style("opacity", context.interpolateFillOpacity())
204
+ .style("stroke", "none")
205
+ .style("fill", context.areaColor([], _d, undefined, []))
206
+ ;
207
+ });
208
+ areas.exit().remove();
209
+
210
+ const lines = element.selectAll(".line").data(layerColumns.filter(function (_d, idx) { return context.interpolate() && idx > 0; }));
211
+ const linesEnter = lines.enter().append("path");
212
+ const line = d3Line()
213
+ .x(function (d) { return context.xPos(host, d); })
214
+ .y(function (d) { return context.yPos(host, d); })
215
+ .curve(this.curve())
216
+ ;
217
+ linesEnter.merge(lines)
218
+ .attr("class", d => "line series series-" + this.cssTag(d))
219
+ .each(function (_d, idx) {
220
+ const element = d3Select(this);
221
+ const data2 = flatData.filter(function (d2) { return d2.colIdx === idx + 1; });
222
+ element
223
+ .attr("d", line(data2))
224
+ .style("stroke", context.lineColor([], _d, undefined, []))
225
+ .style("fill", "none")
226
+ ;
227
+ });
228
+ lines.exit().remove();
229
+
230
+ const points = element.selectAll(".point").data(flatData, function (d, idx) { return d.shape + "_" + idx; });
231
+ points.enter().append("g")
232
+ .each(function (this: SVGElement, d2) {
233
+ const element = d3Select(this);
234
+ element
235
+ .append(d2.shape)
236
+ .attr("class", "pointShape")
237
+ ;
238
+ element
239
+ .append("text")
240
+ .attr("class", "pointValue")
241
+ .style("display", "none")
242
+ .attr("text-anchor", context.valueAnchor())
243
+ .attr("alignment-baseline", context.valueBaseline())
244
+ .attr("fill", function (d: any, _idx) {
245
+ const useTextColor = context.valueBaseline() === "middle" || context.valueBaseline() === "central";
246
+ return useTextColor ? context.textColor(d.row, d.column, d.value, d.origRow) : null;
247
+ })
248
+ ;
249
+ element
250
+ .append("circle")
251
+ .attr("class", "pointSelection")
252
+ .on("mouseout.tooltip", context.tooltip.hide)
253
+ .on("mousemove.tooltip", context.tooltip.show)
254
+ .call(host._selection.enter.bind(host._selection))
255
+ .on("click", function (d: any, _idx) {
256
+ context.click(host.rowToObj(host.data()[d.rowIdx]), d.column, host._selection.selected(this));
257
+ })
258
+ .on("dblclick", function (d: any, _idx) {
259
+ context.dblclick(host.rowToObj(host.data()[d.rowIdx]), d.column, host._selection.selected(this));
260
+ })
261
+ ;
262
+ })
263
+ .merge(points)
264
+ .attr("class", d => "point series series-" + this.cssTag(d.column))
265
+ .each(function (this: SVGElement, d2) {
266
+ const textSelection = d3Select(this).select(".pointValue");
267
+ textSelection
268
+ .attr("x", function (d) { return context.xPos(host, d); })
269
+ .attr("y", function (d) { return context.yPos(host, d); })
270
+ .style("display", context.showValue() ? "block" : "none")
271
+ .attr("text-anchor", context.valueAnchor())
272
+ .attr("alignment-baseline", context.valueBaseline())
273
+ .text(function (d) {
274
+ return d["value"];
275
+ })
276
+ ;
277
+ const elementSelection = d3Select(this).select(".pointSelection");
278
+ elementSelection
279
+ .attr("cx", function (d) { return context.xPos(host, d); })
280
+ .attr("cy", function (d) { return context.yPos(host, d); })
281
+ .attr("r", d2.size)
282
+ ;
283
+
284
+ const element = d3Select(this).select(".pointShape");
285
+ switch (d2.shape) {
286
+ case "rect":
287
+ element
288
+ .attr("x", function (d) { return context.xPos(host, d) - d2.size / 2; })
289
+ .attr("y", function (d) { return context.yPos(host, d) - d2.size / 2; })
290
+ .attr("width", d2.size)
291
+ .attr("height", d2.size)
292
+ .style("fill", context.pointColor(d2.row, d2.column, d2.value, d2.origRow))
293
+ ;
294
+ break;
295
+ case "circle":
296
+ element
297
+ .attr("cx", function (d) { return context.xPos(host, d); })
298
+ .attr("cy", function (d) { return context.yPos(host, d); })
299
+ .attr("r", d2.size * 0.9)
300
+ .style("fill", context.pointColor(d2.row, d2.column, d2.value, d2.origRow))
301
+ ;
302
+ break;
303
+ case "path":
304
+ element
305
+ .attr("d", function (d: any) {
306
+ return "M" + (context.xPos(host, d) - d2.size / 2) + " " + (context.yPos(host, d) - d2.size / 2) + " " +
307
+ "L" + (context.xPos(host, d) + d2.size / 2) + " " + (context.yPos(host, d) + d2.size / 2) + " " +
308
+ "M" + (context.xPos(host, d) - d2.size / 2) + " " + (context.yPos(host, d) + d2.size / 2) + " " +
309
+ "L" + (context.xPos(host, d) + d2.size / 2) + " " + (context.yPos(host, d) - d2.size / 2);
310
+ })
311
+ .style("stroke", context.pointColor(d2.row, d2.column, d2.value, d2.origRow))
312
+ ;
313
+ break;
314
+ default:
315
+ }
316
+ })
317
+ ;
318
+ points.exit().remove();
319
+ }
320
+
321
+ exit(domNode, element) {
322
+ super.exit(domNode, element);
323
+ }
324
+
325
+ paletteID: { (): string; (_: string): Scatter; };
326
+ useClonedPalette: { (): boolean; (_: boolean): Scatter; };
327
+ pointSizeScale: { (): string; (_: string): Scatter; };
328
+ pointShape: { (): string; (_: string): Scatter; };
329
+ pointSize: { (): number; (_: number): Scatter; };
330
+ interpolate: { (): string; (_: string): Scatter; };
331
+ interpolate_default: { (): string; (_: string): Scatter; };
332
+ interpolateFill: { (): boolean; (_: boolean): Scatter; };
333
+ interpolateFill_default: { (): boolean; (_: boolean): Scatter; };
334
+ interpolateFillOpacity: { (): number; (_: number): Scatter; };
335
+
336
+ // INDChart
337
+ _palette;
338
+ fillColor: (row, column, value, origRow) => string;
339
+ strokeColor: (row, column, value, origRow) => string;
340
+ textColor: (row, column, value, origRow) => string;
341
+ dblclick: (row, column, selected) => void;
342
+
343
+ // ITooltip
344
+ tooltip;
345
+ tooltipHTML: (_) => string;
346
+ tooltipFormat: (_) => string;
347
+ tooltipStyle: () => "default" | "none" | "series-table";
348
+ }
349
+ Scatter.prototype._class += " chart_Scatter";
350
+ Scatter.prototype.implements(INDChart.prototype);
351
+ Scatter.prototype.implements(ITooltip.prototype);
352
+ export interface Scatter {
353
+ valueAnchor(): string;
354
+ valueAnchor(_: string): this;
355
+ valueBaseline(): string;
356
+ valueBaseline(_: string): this;
357
+ showValue(): boolean;
358
+ showValue(_: boolean): this;
359
+ pointDarken(): boolean;
360
+ pointDarken(_: boolean): this;
361
+ interpolateDarken(): boolean;
362
+ interpolateDarken(_: boolean): this;
363
+ }
364
+ Scatter.prototype.publish("paletteID", "default", "set", "Color palette for this widget", Scatter.prototype._palette.switch(), { tags: ["Basic", "Shared"] });
365
+ Scatter.prototype.publish("pointSizeScale", "linear", "set", "pointSizeScale", ["linear", "pow", "log", "sqrt"]);
366
+ Scatter.prototype.publish("pointShape", "cross", "set", "Shape of the data points", ["circle", "rectangle", "cross"]);
367
+ Scatter.prototype.publish("pointSize", 6, "number", "Point Size", null, { range: { min: 1, step: 1, max: 200 } });
368
+ Scatter.prototype.publish("interpolate", "", "set", "Interpolate Data", ["", "linear", "step", "step-before", "step-after", "basis", "bundle", "cardinal", "catmullRom", "natural", "monotone"]);
369
+ Scatter.prototype.publish("pointDarken", true, "boolean", "If true, and interpolate is set, then points will have a slightly darker color than their assigned palette color", null, { disable: w => !w.interpolate() });
370
+ Scatter.prototype.publish("interpolateDarken", true, "boolean", "If true, and interpolateFill is true, then lines will have a slightly darker color than their assigned palette color", null, { disable: w => !w.interpolateFill() });
371
+ Scatter.prototype.publish("interpolateFill", false, "boolean", "If true, the area between the line and zero will be filled");
372
+ Scatter.prototype.publish("interpolateFillOpacity", 0.66, "number", "Fill interpolation Opacity", null, { range: { min: 0, step: 0.01, max: 1 } });
373
+ Scatter.prototype.publish("useClonedPalette", false, "boolean", "Enable or disable using a cloned palette", null, { tags: ["Intermediate", "Shared"] });
374
+ Scatter.prototype.publish("showValue", false, "boolean");
375
+ Scatter.prototype.publish("valueAnchor", "middle", "set", "text-anchor for shown value text", ["start", "middle", "end"]);
376
+ Scatter.prototype.publish("valueBaseline", "ideographic", "set", "alignment-baseline for shown value text", ["auto", "baseline", "before-edge", "text-before-edge", "middle", "central", "after-edge", "text-after-edge", "ideographic", "alphabetic", "hanging", "mathematical", "inherit"]);