@hpcc-js/chart 3.6.5 → 3.6.6

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 +4 -4
  8. package/src/Area.md +176 -176
  9. package/src/Area.ts +12 -12
  10. package/src/Axis.css +34 -34
  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 +60 -60
  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 +9 -9
  36. package/src/HexBin.md +88 -88
  37. package/src/HexBin.ts +144 -144
  38. package/src/Line.css +6 -6
  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 +15 -15
  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 +56 -56
  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 +3 -3
  67. package/src/WordCloud.md +144 -144
  68. package/src/WordCloud.ts +268 -268
  69. package/src/XYAxis.css +41 -41
  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/XYAxis.ts CHANGED
@@ -1,809 +1,809 @@
1
- import { d3Event, select as d3Select, SVGWidget, Utility } from "@hpcc-js/common";
2
- import { max as d3Max, min as d3Min } from "d3-array";
3
- import { brush as d3Brush, brushSelection as d3BrushSelection, brushX as d3BrushX, brushY as d3BrushY } from "d3-brush";
4
- import { hsl as d3Hsl } from "d3-color";
5
- import { Axis } from "./Axis.ts";
6
-
7
- import "../src/XYAxis.css";
8
-
9
- export class XYAxis extends SVGWidget {
10
- protected domainAxis: Axis;
11
- protected valueAxis: Axis;
12
- protected xAxis: Axis;
13
- protected yAxis: Axis;
14
- protected xyBrush;
15
- protected xBrush;
16
- protected yBrush;
17
- protected margin;
18
- protected focusChart: XYAxis;
19
-
20
- constructor() {
21
- super();
22
- Utility.SimpleSelectionMixin.call(this);
23
-
24
- this._drawStartPos = "origin";
25
-
26
- this.domainAxis = new Axis()
27
- .classed({ domain: true })
28
- .orientation_default("bottom")
29
- .type("ordinal")
30
- .overlapMode_default("stagger")
31
- .shrinkToFit_default("high")
32
- .extend_default(0)
33
- ;
34
- this.valueAxis = new Axis()
35
- .classed({ value: true })
36
- .orientation_default("left")
37
- .type("linear")
38
- .shrinkToFit_default("high")
39
- ;
40
-
41
- this.xyBrush = d3Brush()
42
- .on("end", () => {
43
- return this.brushMoved();
44
- })
45
- .on("start.handle brush.handle end.handle", () => {
46
- return this.brushMoved2();
47
- })
48
- ;
49
- this.xBrush = d3BrushX()
50
- .on("end", () => {
51
- return this.brushMoved();
52
- })
53
- .on("start.handle brush.handle end.handle", () => {
54
- return this.brushMoved2();
55
- })
56
- ;
57
- this.yBrush = d3BrushY()
58
- .on("end", () => {
59
- return this.brushMoved();
60
- })
61
- .on("start.handle brush.handle end.handle", () => {
62
- return this.brushMoved2();
63
- })
64
- ;
65
- }
66
-
67
- protected _prevBrush;
68
- resetSelection() {
69
- this._prevBrush = null;
70
- return this;
71
- }
72
-
73
- parseData(d) {
74
- return this.domainAxis.parse(d);
75
- }
76
-
77
- parseValue(d) {
78
- return this.valueAxis.parse(d, true);
79
- }
80
-
81
- formatData(d) {
82
- return this.domainAxis.format(d);
83
- }
84
-
85
- formatValue(d) {
86
- return this.valueAxis.format(d);
87
- }
88
-
89
- parsedData() {
90
- const retVal = this.data().map(function (row) {
91
- let prevValue = 0;
92
- return row.map(function (cell, idx) {
93
- if (idx === 0) {
94
- return this.parseData(cell);
95
- }
96
- if (idx >= this.columns().length) {
97
- return cell;
98
- }
99
- const _retVal = this.yAxisStacked() ? [prevValue, prevValue + this.parseValue(cell)] : this.parseValue(cell);
100
- prevValue += this.parseValue(cell);
101
- return _retVal;
102
- }, this);
103
- }, this);
104
- return retVal;
105
- }
106
-
107
- bandwidth() {
108
- return this.domainAxis.bandwidth();
109
- }
110
-
111
- protected svg;
112
- protected svgRegions;
113
- protected svgDomainGuide;
114
- protected svgValueGuide;
115
- protected svgData;
116
- protected svgDataClipRect;
117
- protected svgFocus;
118
- protected svgBrush;
119
- enter(domNode, element) {
120
- super.enter(domNode, element);
121
- this.svg = element.append("g");
122
- this.svgRegions = element.append("g");
123
- this.svgDomainGuide = this.svg.append("g");
124
- this.svgValueGuide = this.svg.append("g");
125
- this.svgData = this.svg.append("g");
126
-
127
- this.svgDataClipRect = this.svg.append("clipPath")
128
- .attr("id", this.id() + "_clippath")
129
- .append("rect")
130
- .attr("x", 0)
131
- .attr("y", 0)
132
- ;
133
- this.svgData = this.svg.append("g")
134
- .attr("clip-path", "url(#" + this.id() + "_clippath)")
135
- ;
136
- this._selection.widgetElement(this.svgData);
137
-
138
- this.svgFocus = element.append("g");
139
-
140
- this.domainAxis
141
- .target(this.svg.node())
142
- .guideTarget(this.svgDomainGuide.node())
143
- ;
144
-
145
- this.valueAxis
146
- .target(this.svg.node())
147
- .guideTarget(this.svgValueGuide.node())
148
- ;
149
-
150
- this.svgBrush = element.append("g")
151
- .attr("class", "brush")
152
- ;
153
- this.chartsEnter(this, this.svgData, 250);
154
- }
155
-
156
- resizeBrushHandle(d, width, height) {
157
- let e;
158
- let x;
159
- let y;
160
- if (d.type === "e" || d.type === "w") {
161
- e = +(d.type === "e");
162
- x = e ? 1 : -1;
163
- y = height / 3;
164
- return "M" + (0.5 * x) + "," + y +
165
- "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6) +
166
- "V" + (2 * y - 6) +
167
- "A6,6 0 0 " + e + " " + (0.5 * x) + "," + (2 * y) +
168
- "Z" +
169
- "M" + (2.5 * x) + "," + (y + 8) +
170
- "V" + (2 * y - 8) +
171
- "M" + (4.5 * x) + "," + (y + 8) +
172
- "V" + (2 * y - 8);
173
- } else {
174
- e = +(d.type === "s");
175
- y = e ? 1 : -1;
176
- x = width / 3;
177
- return "M" + x + ", " + (0.5 * y) +
178
- "A6,6 0 0 " + (e + 1) % 2 + " " + (x + 6) + "," + (6.5 * y) +
179
- "H" + (2 * x - 6) +
180
- "A6,6 0 0 " + (e + 1) % 2 + " " + (2 * x) + "," + (0.5 * y) +
181
- "Z" +
182
- "M" + (x + 8) + "," + (2.5 * y) +
183
- "H" + (2 * x - 8) +
184
- "M" + (x + 8) + "," + (4.5 * y) +
185
- "H" + (2 * x - 8);
186
- }
187
- }
188
-
189
- private _skipSelection = false;
190
- skipSelection(): boolean;
191
- skipSelection(_: boolean): this;
192
- skipSelection(_?: boolean): boolean | this {
193
- if (!arguments.length) return this._skipSelection;
194
- this._skipSelection = _;
195
- return this;
196
- }
197
-
198
- brushMoved() {
199
- if (this._skipSelection) return;
200
- let selected = [];
201
- const context = this;
202
- const currSel: any = d3BrushSelection(this.svgBrush.node());
203
- if (currSel) {
204
- selected = this.data().filter(function (d) {
205
- const pos = context.dataPos(d[0]);
206
- if (context.use2dSelection()) {
207
- const pos2 = context.valuePos(d[1]) + context.valueAxis.bandwidth() / 2;
208
- return pos >= currSel[0][0] && pos <= currSel[1][0] && pos2 >= currSel[0][1] && pos2 <= currSel[1][1];
209
- } else {
210
- return pos >= currSel[0] && pos <= currSel[1];
211
- }
212
- });
213
- }
214
- this.selection(selected);
215
- }
216
-
217
- brushMoved2() {
218
- const isHorizontal = this.orientation() === "horizontal";
219
- const handleTypes = this.use2dSelection() ? [] : isHorizontal ? [{ type: "w" }, { type: "e" }] : [{ type: "n" }, { type: "s" }];
220
- const handlePath = this.svgBrush.selectAll(".handle--custom").data(handleTypes);
221
- const s = d3Event()?.selection;
222
- if (s == null) {
223
- handlePath.attr("display", "none");
224
- } else if (isHorizontal) {
225
- handlePath.attr("display", null).attr("transform", (_d, i) => "translate(" + s[i] + "," + 0 + ")");
226
- } else {
227
- handlePath.attr("display", null).attr("transform", (_d, i) => "translate(" + 0 + ", " + s[i] + ")");
228
- }
229
- }
230
-
231
- dataPos(d) {
232
- return this.domainAxis.scalePos(d);
233
- }
234
-
235
- valuePos(d) {
236
- return this.valueAxis.scalePos(d);
237
- }
238
-
239
- getAxisSize(host: XYAxis): { width: number, height: number } {
240
- return {
241
- width: !this.xAxis ? host.xAxis.width() : this.xAxis.width(),
242
- height: !this.yAxis ? host.yAxis.width() : this.yAxis.height()
243
- };
244
- }
245
-
246
- calcMargin(_domNode, element, isHorizontal) {
247
- const margin = {
248
- top: !isHorizontal && this.selectionMode() ? 10 : 2,
249
- right: isHorizontal && (this.selectionMode() || this.xAxisFocus()) ? 10 : 2,
250
- bottom: (this.xAxisFocus() ? this.xAxisFocusHeight() : 0) + 2,
251
- left: 2
252
- };
253
- const width = this.width() - margin.left - margin.right;
254
- const height = this.height() - margin.top - margin.bottom;
255
-
256
- let xRight = 0;
257
- let xHeight = 30;
258
- let yTop = 0;
259
- let yWidth = 30;
260
- for (let i = 0; i < 10; ++i) {
261
- this.xAxis.width(width - yWidth).height(0);
262
- const xAxisOverlap = this.xAxis.calcOverflow(element);
263
- const newXHeight = xAxisOverlap.depth;
264
-
265
- this.yAxis.width(0).height(height - xHeight);
266
- const yAxisOverlap = this.yAxis.calcOverflow(element);
267
- const newYWidth = yAxisOverlap.depth;
268
-
269
- xRight = xAxisOverlap.right;
270
- yTop = yAxisOverlap.top;
271
-
272
- if (newXHeight === xHeight && newYWidth === yWidth) {
273
- break;
274
- }
275
- xHeight = newXHeight;
276
- yWidth = newYWidth;
277
- }
278
- this.xAxis
279
- .x(width / 2 + yWidth / 2 + margin.left)
280
- .y(height + margin.top)
281
- .width(width - yWidth)
282
- ;
283
- this.yAxis
284
- .x(margin.left)
285
- .y(height / 2 - xHeight / 2 + margin.top)
286
- .height(height - xHeight)
287
- ;
288
- margin.left += yWidth;
289
- margin.top += yTop;
290
- margin.right += xRight;
291
- margin.bottom += xHeight;
292
- return margin;
293
- }
294
-
295
- updateRegions(_domNode, _element, isHorizontal) {
296
- const context = this;
297
-
298
- const regions = this.svgRegions.selectAll(".region").data(this.regions());
299
- regions.enter().append("rect")
300
- .attr("class", "region")
301
- ;
302
- if (isHorizontal) {
303
- regions
304
- .attr("x", function (d) { return context.dataPos(d.x0); })
305
- .attr("y", 0)
306
- .attr("width", function (d) { return context.dataPos(d.x1) - context.dataPos(d.x0); })
307
- .attr("height", this.height())
308
- .style("stroke", function (d) { return context._palette(d.colorID); })
309
- .style("fill", function (d) { return d3Hsl(context._palette(d.colorID)).brighter(); })
310
- ;
311
- } else {
312
- regions
313
- .attr("x", 0)
314
- .attr("y", function (d) { return context.dataPos(d.x0); })
315
- .attr("width", this.width())
316
- .attr("height", function (d) { return context.dataPos(d.x0) - context.dataPos(d.x1); })
317
- .style("stroke", function (d) { return context._palette(d.colorID); })
318
- .style("fill", function (d) { return d3Hsl(context._palette(d.colorID)).brighter(); })
319
- ;
320
- }
321
- regions.exit().remove();
322
- }
323
-
324
- protected _prevXAxisType;
325
- update(domNode, element) {
326
- this.selectionGlow(!this.tabNavigation());
327
- super.update(domNode, element);
328
- const context = this;
329
-
330
- const isHorizontal = this.orientation() === "horizontal";
331
- this.updateRegions(domNode, element, isHorizontal);
332
-
333
- this.domainAxis
334
- .orientation(isHorizontal ? "bottom" : "left")
335
- .title(this.xAxisTitle_exists() ? this.xAxisTitle() : this.columns()[0])
336
- ;
337
- this.valueAxis
338
- .orientation(isHorizontal ? "left" : "bottom")
339
- ;
340
- this.xAxis = isHorizontal ? this.domainAxis : this.valueAxis;
341
- this.yAxis = isHorizontal ? this.valueAxis : this.domainAxis;
342
-
343
- // Update Domain ---
344
- switch (this.xAxisType()) {
345
- case "ordinal":
346
- const colLen = this.columns().length;
347
- const ordinalMappings = {};
348
- this.domainAxis
349
- .ordinals(this.data().map(function (d) {
350
- ordinalMappings[d[0]] = context.xAxisOrdinalMapping(d, d[colLen]);
351
- return d[0];
352
- }))
353
- .ordinalMappings(ordinalMappings)
354
- ;
355
-
356
- break;
357
- default:
358
- const domainMin = this.xAxisDomainLow() ? this.xAxisDomainLow() : this.domainAxis.parseInvert(d3Min(this.parsedData(), function (data) {
359
- return data[0];
360
- }));
361
- const domainMax = this.xAxisDomainHigh() ? this.xAxisDomainHigh() : this.domainAxis.parseInvert(d3Max(this.parsedData(), function (data) {
362
- return data[0];
363
- }));
364
- if (domainMin !== undefined && domainMax !== undefined) {
365
- this.domainAxis
366
- .low(domainMin)
367
- .high(domainMax)
368
- ;
369
- }
370
- break;
371
- }
372
-
373
- const min = this.yAxisDomainLow() ? this.yAxisDomainLow() : this.valueAxis.parseInvert(d3Min(this.parsedData(), function (data: any[]) {
374
- return d3Min(data.filter(function (cell, i) { return i > 0 && context.columns()[i] && context.columns()[i].indexOf("__") !== 0 && cell !== null; }), function (d) { return d instanceof Array ? d[0] : d; });
375
- }));
376
- const max = this.yAxisDomainHigh() ? this.yAxisDomainHigh() : this.valueAxis.parseInvert(d3Max(this.parsedData(), function (data: any[]) {
377
- return d3Max(data.filter(function (cell, i) { return i > 0 && context.columns()[i] && context.columns()[i].indexOf("__") !== 0 && cell !== null; }), function (d) { return d instanceof Array ? d[1] : d; });
378
- }));
379
- this.valueAxis
380
- .low(min)
381
- .high(max)
382
- ;
383
-
384
- // Calculate Margins ---
385
- this.margin = this.calcMargin(domNode, element, isHorizontal);
386
-
387
- // Update Range ---
388
- let width = this.width() - this.margin.left - this.margin.right;
389
- if (width < 0) width = 0;
390
- let height = this.height() - this.margin.top - this.margin.bottom;
391
- if (height < 0) height = 0;
392
- const maxCurrExtent = isHorizontal ? width : height;
393
- const maxOtherExtent = isHorizontal ? height : width;
394
-
395
- // Render ---
396
- this.domainAxis
397
- .tickLength(this.xAxisGuideLines() ? maxOtherExtent : 0)
398
- .render()
399
- ;
400
- this.valueAxis
401
- .tickLength(this.yAxisGuideLines() ? maxCurrExtent : 0)
402
- .render()
403
- ;
404
-
405
- this.svgDataClipRect
406
- .attr("width", width)
407
- .attr("height", height)
408
- ;
409
- this.svgData.transition()
410
- .attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")")
411
- ;
412
-
413
- this.updateBrush(width, height, maxCurrExtent, isHorizontal);
414
- this.updateFocusChart(domNode, element, this.margin, width, height, isHorizontal);
415
- this.chartsUpdate(width, height, 250);
416
- if (this.selectionMode()) {
417
- return this.brushMoved();
418
- }
419
- }
420
-
421
- updateBrush(width, height, maxCurrExtent, isHorizontal) {
422
- const currBrush = this.use2dSelection() ? this.xyBrush : isHorizontal ? this.xBrush : this.yBrush;
423
- const prevBrushSel: any = d3BrushSelection(this.svgBrush.node());
424
- currBrush.extent([[0, 0], [width, height]]);
425
- this.svgBrush
426
- .attr("transform", "translate(" + this.margin.left + ", " + this.margin.top + ")")
427
- .style("display", this.selectionMode() ? null : "none")
428
- .call(currBrush)
429
- ;
430
- const handleTypes = this.use2dSelection() ? [] : isHorizontal ? [{ type: "w" }, { type: "e" }] : [{ type: "n" }, { type: "s" }];
431
- const handlePath = this.svgBrush.selectAll(".handle--custom").data(handleTypes);
432
- handlePath.enter().append("path")
433
- .attr("class", "handle--custom")
434
- .merge(handlePath)
435
- .attr("cursor", isHorizontal ? "ew-resize" : "ns-resize")
436
- .attr("d", (d) => this.resizeBrushHandle(d, width, height))
437
- ;
438
-
439
- if (this.selectionMode()) {
440
- if (this._prevXAxisType !== this.xAxisType()) {
441
- this._prevXAxisType = this.xAxisType();
442
- this._prevBrush = null;
443
- }
444
- if (this._prevBrush) {
445
- if (prevBrushSel) {
446
- if (this._prevBrush.orientation !== this.orientation()) {
447
- const tmp = prevBrushSel[0];
448
- prevBrushSel[0] = this._prevBrush.maxCurrExtent - prevBrushSel[1];
449
- prevBrushSel[1] = this._prevBrush.maxCurrExtent - tmp;
450
- }
451
- const ratio = maxCurrExtent / this._prevBrush.maxCurrExtent;
452
- if (ratio !== 1) {
453
- this.svgBrush.transition()
454
- .on("start", function () {
455
- currBrush.on("end", null);
456
- })
457
- .call(currBrush.move, [prevBrushSel[0] * ratio, prevBrushSel[1] * ratio])
458
- .on("end", () => {
459
- currBrush.on("end", () => {
460
- return this.brushMoved();
461
- });
462
- })
463
- ;
464
- }
465
- }
466
- } else {
467
- this.svgBrush
468
- .call(currBrush.move, [0, maxCurrExtent])
469
- ;
470
- }
471
- this._prevBrush = {
472
- orientation: this.orientation(),
473
- maxCurrExtent
474
- };
475
- }
476
- }
477
-
478
- updateFocusChart(domNode, element, margin, width, height, isHorizontal) {
479
- const context: XYAxis = this;
480
- const focusChart = this.svgFocus.selectAll("#" + this.id() + "_focusChart").data(this.xAxisFocus() ? [true] : []);
481
- focusChart.enter().append("g")
482
- .attr("id", this.id() + "_focusChart")
483
- .attr("class", "focus")
484
- .each(function () {
485
- context.focusChart = new (context.constructor as any)()
486
- .target(this)
487
- ;
488
- context.focusChart.xBrush
489
- .on("brush.focus", function () {
490
- context.syncAxis(width);
491
- context.chartsUpdate(width, height, 0);
492
- })
493
- ;
494
- context.focusChart
495
- .layers(context.layers().map((w: any) => new w.constructor()))
496
- ;
497
- })
498
- .merge(focusChart)
499
- .each(function (this: SVGElement) {
500
- context.copyPropsTo(context.focusChart, ["layers"]);
501
- let layerIdx = 0;
502
- for (const layer of context.layers()) {
503
- layer.copyPropsTo(context.focusChart.layers()[layerIdx]);
504
- layerIdx++;
505
- }
506
- context.focusChart
507
- .xAxisFocus(false)
508
- .selectionMode(true)
509
- .skipSelection(true)
510
- .orientation("horizontal")
511
- .xAxisGuideLines(false)
512
- .xAxisDomainLow(null)
513
- .xAxisDomainHigh(null)
514
- .yAxisGuideLines(false)
515
- .x(context.width() / 2)
516
- .y(context.height() - context.xAxisFocusHeight() / 2)
517
- .width(context.width())
518
- .height(context.xAxisFocusHeight())
519
- .columns(context.columns())
520
- .data(context.data())
521
- .render()
522
- ;
523
- context.syncAxis(width);
524
- })
525
- ;
526
- focusChart.exit()
527
- .each(function () {
528
- if (context.focusChart) {
529
- context.focusChart
530
- .target(null)
531
- ;
532
- delete context.focusChart;
533
- }
534
- })
535
- .remove()
536
- ;
537
- }
538
-
539
- syncAxis(width: number) {
540
- const currSel = d3BrushSelection(this.focusChart.svgBrush.node()) as [number, number];
541
- if (currSel) {
542
- if (this.focusChart.xAxisType() !== "ordinal") {
543
- this.xAxis.domain([this.focusChart.xAxis.invert(currSel[0]), this.focusChart.xAxis.invert(currSel[1])]);
544
- } else {
545
- const brushWidth = currSel[1] - currSel[0];
546
- const scale = brushWidth / width;
547
- this.xAxis.range([-currSel[0] / scale, (width - currSel[0]) / scale]);
548
- }
549
- this.xAxis.rerender();
550
- }
551
- }
552
-
553
- // Layers ---
554
- layerColumns(host: XYAxis): string[] {
555
- const masterColumns = host.columns();
556
- const retVal = super.columns().filter(col => col !== masterColumns[0]);
557
- if (!retVal.length) {
558
- return masterColumns;
559
- }
560
- return [masterColumns[0], ...retVal];
561
- }
562
-
563
- layerColumnIndices(host: XYAxis): number[] {
564
- const masterColumns = host.columns();
565
- const layerColumns = this.layerColumns(host);
566
- return layerColumns.map(col => masterColumns.indexOf(col));
567
- }
568
-
569
- layerColumnIndex(host: XYAxis, column: string): number {
570
- const masterColumns = host.columns();
571
- return masterColumns.indexOf(column);
572
- }
573
-
574
- layerData(host?: XYAxis): any[][] {
575
- if (arguments.length === 1) {
576
- const indices = this.layerColumnIndices(host);
577
- return host.data().map(row => {
578
- const retVal = indices.map(idx => row[idx]);
579
- (retVal as any).__hpcc_origRow = row;
580
- return retVal;
581
- });
582
- }
583
- throw new Error("Setting data on XYAxisLayer is not supported.");
584
- }
585
-
586
- layerEnter(host: XYAxis, element, duration: number = 250) {
587
- }
588
-
589
- layerUpdate(host: XYAxis, element, duration: number = 250) {
590
- }
591
-
592
- layerExit(host: XYAxis, element, duration: number = 250) {
593
- }
594
-
595
- chartsEnter(host: XYAxis, element, duration: number = 250) {
596
- this.layerEnter(this, element, duration);
597
- for (const w of this.layers()) {
598
- w["__xyAxisElement"] = element.append("g")
599
- .attr("class", w.class())
600
- ;
601
- w
602
- .target(w["__xyAxisElement"].node() as SVGElement)
603
- .layerEnter(this, element, duration)
604
- ;
605
- }
606
- }
607
-
608
- chartsUpdate(width, height, duration): void {
609
- this.layerUpdate(this, this.svgData, duration);
610
- for (const w of this.layers()) {
611
- w
612
- .resize({ width, height })
613
- .layerUpdate(this, w["__xyAxisElement"], duration)
614
- ;
615
- }
616
- }
617
-
618
- exit(domNode, element) {
619
- this.valueAxis.target(null);
620
- this.domainAxis.target(null);
621
- super.exit(domNode, element);
622
- }
623
-
624
- selection(_selected) {
625
- const context = this;
626
- this._selection.widgetElement().selectAll(".selected,.deselected")
627
- .each(function (d) {
628
- const selected = _selected.indexOf(d.origRow) >= 0;
629
- d3Select(this)
630
- .classed("selected", selected)
631
- .classed("deselected", !selected)
632
- .attr("filter", context._selection.svgGlowID() && selected ? `url(#${context._selection.svgGlowID()})` : null)
633
- ;
634
- })
635
- ;
636
-
637
- const selRows = _selected.map(d => {
638
- return this.rowToObj(d);
639
- });
640
- setTimeout(() => {
641
- this.click(selRows, "", true);
642
- }, 0);
643
- }
644
-
645
- // XYAxis ---
646
- xAxisOrdinalMapping(origRow, lparam) {
647
- return origRow[0];
648
- }
649
-
650
- // Events ---
651
- click(row, column, selected) {
652
- // console.log("Click: " + JSON.stringify(row) + ", " + column + ", " + selected);
653
- }
654
-
655
- // Selection ---
656
- _selection: Utility.SimpleSelection;
657
- }
658
- XYAxis.prototype._class += " chart_XYAxis";
659
- XYAxis.prototype.mixin(Utility.SimpleSelectionMixin);
660
-
661
- export interface XYAxis {
662
- _palette;
663
- orientation(): "horizontal" | "vertical";
664
- orientation(_: "horizontal" | "vertical"): this;
665
- orientation_default(_: string);
666
- pointSizeColumn(): string;
667
- pointSizeColumn(_: string): this;
668
- pointSizeColumn_exists(): boolean;
669
- minPointSize(): number;
670
- minPointSize(_: number): this;
671
- maxPointSize(): number;
672
- maxPointSize(_: number): this;
673
- use2dSelection(): boolean;
674
- use2dSelection(_: boolean): this;
675
- selectionMode(): boolean;
676
- selectionMode(_: boolean): this;
677
- xAxisTitle(): string;
678
- xAxisTitle(_: string): this;
679
- xAxisTitle_exists(): boolean;
680
- xAxisTickCount(): number;
681
- xAxisTickCount(_: number): this;
682
- xAxisTickFormat(): string;
683
- xAxisTickFormat(_: string): this;
684
- xAxisTicks(): Array<{ value: string, label: string }>;
685
- xAxisTicks(_: Array<{ value: string, label: string }>): this;
686
- xAxisType(): "none" | "ordinal" | "linear" | "pow" | "log" | "time";
687
- xAxisType(_: "none" | "ordinal" | "linear" | "pow" | "log" | "time"): this;
688
- xAxisType_default(_: string);
689
- xAxisTypeTimePattern(): string;
690
- xAxisTypeTimePattern(_: string): this;
691
- xAxisDomainLow(): number | string;
692
- xAxisDomainLow(_: number | string): this;
693
- xAxisDomainHigh(): number | string;
694
- xAxisDomainHigh(_: number | string): this;
695
- xAxisFontSize(): number | string;
696
- xAxisFontSize(_: number | string): this;
697
- xAxisFontFamily(): string;
698
- xAxisFontFamily(_: string): this;
699
- xAxisOrdinalPaddingInner(): number;
700
- xAxisOrdinalPaddingInner(_: number): this;
701
- xAxisOrdinalPaddingOuter(): number;
702
- xAxisOrdinalPaddingOuter(_: number): this;
703
- xAxisOverlapMode(): "none" | "stagger" | "hide" | "rotate" | "linebreak" | "wrap";
704
- xAxisOverlapMode(_: "none" | "stagger" | "hide" | "rotate" | "linebreak" | "wrap"): this;
705
- xAxisLabelRotation(): number;
706
- xAxisLabelRotation(_: number): this;
707
- xAxisDomainPadding(): number;
708
- xAxisDomainPadding(_: number): this;
709
- xAxisGuideLines(): boolean;
710
- xAxisGuideLines(_: boolean): this;
711
- xAxisGuideLines_default(_: boolean);
712
- xAxisFocus(): boolean;
713
- xAxisFocus(_: boolean): this;
714
- xAxisFocusHeight(): number;
715
- xAxisFocusHeight(_: number): this;
716
- xAxisHidden(): boolean;
717
- xAxisHidden(_: boolean): this;
718
- xAxisHidden_default(_: boolean);
719
- yAxisTitle(): string;
720
- yAxisTitle(_: string): this;
721
- yAxisTickCount(): number;
722
- yAxisTickCount(_: number): this;
723
- yAxisTickFormat(): string;
724
- yAxisTickFormat(_: string): this;
725
- yAxisTicks(): Array<{ value: string, label: string }>;
726
- yAxisTicks(_: Array<{ value: string, label: string }>): this;
727
- yAxisType(): "none" | "ordinal" | "linear" | "pow" | "log" | "time";
728
- yAxisType(_: "none" | "ordinal" | "linear" | "pow" | "log" | "time"): this;
729
- yAxisType_default(_: string);
730
- yAxisTypeTimePattern(): string;
731
- yAxisTypeTimePattern(_: string): this;
732
- yAxisTypePowExponent(): number;
733
- yAxisTypePowExponent(_: number): this;
734
- yAxisTypeLogBase(): number;
735
- yAxisTypeLogBase(_: number): this;
736
- yAxisStacked(): boolean;
737
- yAxisStacked(_: boolean): this;
738
- yAxisDomainLow(): number | string;
739
- yAxisDomainLow(_: number | string): this;
740
- yAxisDomainHigh(): number | string;
741
- yAxisDomainHigh(_: number | string): this;
742
- yAxisDomainPadding(): number;
743
- yAxisDomainPadding(_: number): this;
744
- yAxisGuideLines(): boolean;
745
- yAxisGuideLines(_: boolean): this;
746
- yAxisGuideLines_default(_: boolean);
747
- yAxisHidden(): boolean;
748
- yAxisHidden(_: boolean): this;
749
- yAxisHidden_default(_: boolean);
750
- regions(): object[];
751
- regions(_: object[]): this;
752
- layers(): XYAxis[];
753
- layers(_: XYAxis[]): this;
754
- xAxisPadding(): number;
755
- xAxisPadding(_: number): this;
756
- yAxisPadding(): number;
757
- yAxisPadding(_: number): this;
758
-
759
- // Tab Navigation
760
- tabNavigation(): boolean;
761
- tabNavigation(_: boolean): this;
762
- }
763
-
764
- XYAxis.prototype.publish("orientation", "horizontal", "set", "Selects orientation for the axis", ["horizontal", "vertical"]);
765
- XYAxis.prototype.publish("pointSizeColumn", null, "string", "pointSizeColumn", null, { optional: true });
766
- XYAxis.prototype.publish("minPointSize", 6, "number", "minPointSize");
767
- XYAxis.prototype.publish("maxPointSize", 26, "number", "maxPointSize");
768
- XYAxis.prototype.publish("use2dSelection", false, "boolean", "2D Range Selector");
769
- XYAxis.prototype.publish("selectionMode", false, "boolean", "Range Selector");
770
- XYAxis.prototype.publishProxy("xAxisTitle", "domainAxis", "title");
771
- XYAxis.prototype.publishProxy("xAxisTickCount", "domainAxis", "tickCount");
772
- XYAxis.prototype.publishProxy("xAxisTickFormat", "domainAxis", "tickFormat");
773
- XYAxis.prototype.publishProxy("xAxisTicks", "domainAxis", "ticks");
774
- XYAxis.prototype.publishProxy("xAxisType", "domainAxis", "type");
775
- XYAxis.prototype.publishProxy("xAxisTypeTimePattern", "domainAxis", "timePattern");
776
- XYAxis.prototype.publish("xAxisDomainLow", null, "string", "X-Axis Low", null, { optional: true, disable: (w: XYAxis) => w.xAxisType() === "ordinal" });
777
- XYAxis.prototype.publish("xAxisDomainHigh", null, "string", "X-Axis High", null, { optional: true, disable: (w: XYAxis) => w.xAxisType() === "ordinal" });
778
- XYAxis.prototype.publishProxy("xAxisFontSize", "domainAxis", "fontSize");
779
- XYAxis.prototype.publishProxy("xAxisFontFamily", "domainAxis", "fontFamily");
780
- XYAxis.prototype.publishProxy("xAxisOrdinalPaddingInner", "domainAxis", "ordinalPaddingInner");
781
- XYAxis.prototype.publishProxy("xAxisOrdinalPaddingOuter", "domainAxis", "ordinalPaddingOuter");
782
- XYAxis.prototype.publishProxy("xAxisOverlapMode", "domainAxis", "overlapMode");
783
- XYAxis.prototype.publishProxy("xAxisLabelRotation", "domainAxis", "labelRotation");
784
- XYAxis.prototype.publishProxy("xAxisDomainPadding", "domainAxis", "extend");
785
- XYAxis.prototype.publish("xAxisGuideLines", false, "boolean", "Y-Axis Guide Lines");
786
- XYAxis.prototype.publish("xAxisFocus", false, "boolean", "X-Axis Focus", null, { disable: (w: any) => w.orientation() !== "horizontal" });
787
- XYAxis.prototype.publish("xAxisFocusHeight", 80, "number", "X-Axis Focus Height", null, { disable: (w: any) => !w.xAxisFocus() });
788
- XYAxis.prototype.publishProxy("xAxisHidden", "domainAxis", "hidden");
789
- XYAxis.prototype.publishProxy("yAxisFontSize", "valueAxis", "fontSize");
790
- XYAxis.prototype.publishProxy("yAxisFontFamily", "valueAxis", "fontFamily");
791
- XYAxis.prototype.publishProxy("yAxisTitle", "valueAxis", "title");
792
- XYAxis.prototype.publishProxy("yAxisTickCount", "valueAxis", "tickCount");
793
- XYAxis.prototype.publishProxy("yAxisTickFormat", "valueAxis", "tickFormat");
794
- XYAxis.prototype.publishProxy("yAxisTicks", "valueAxis", "ticks");
795
- XYAxis.prototype.publishProxy("yAxisType", "valueAxis", "type");
796
- XYAxis.prototype.publishProxy("yAxisTypeTimePattern", "valueAxis", "timePattern");
797
- XYAxis.prototype.publishProxy("yAxisTypePowExponent", "valueAxis", "powExponent");
798
- XYAxis.prototype.publishProxy("yAxisTypeLogBase", "valueAxis", "logBase");
799
- XYAxis.prototype.publish("yAxisStacked", false, "boolean", "Stacked Chart", null, { tags: ["Basic"], disable: (w: any) => w.xAxisType() !== "ordinal" || w._class.indexOf("chart_Column") < 0 });
800
- XYAxis.prototype.publish("yAxisDomainLow", null, "string", "Y-Axis Low", null, { optional: true, disable: (w: any) => w.yAxisType() === "ordinal" });
801
- XYAxis.prototype.publish("yAxisDomainHigh", null, "string", "Y-Axis High", null, { optional: true, disable: (w: any) => w.yAxisType() === "ordinal" });
802
- XYAxis.prototype.publishProxy("yAxisDomainPadding", "valueAxis", "extend");
803
- XYAxis.prototype.publish("yAxisGuideLines", true, "boolean", "Y-Axis Guide Lines");
804
- XYAxis.prototype.publishProxy("yAxisHidden", "valueAxis", "hidden");
805
- XYAxis.prototype.publish("regions", [], "array", "Regions");
806
- XYAxis.prototype.publish("layers", [], "widgetArray", "Layers", null, { render: false });
807
- XYAxis.prototype.publishProxy("xAxisPadding", "domainAxis", "padding");
808
- XYAxis.prototype.publishProxy("yAxisPadding", "valueAxis", "padding");
809
- XYAxis.prototype.publish("tabNavigation", false, "boolean", "Enable or disable tab navigation");
1
+ import { d3Event, select as d3Select, SVGWidget, Utility } from "@hpcc-js/common";
2
+ import { max as d3Max, min as d3Min } from "d3-array";
3
+ import { brush as d3Brush, brushSelection as d3BrushSelection, brushX as d3BrushX, brushY as d3BrushY } from "d3-brush";
4
+ import { hsl as d3Hsl } from "d3-color";
5
+ import { Axis } from "./Axis.ts";
6
+
7
+ import "../src/XYAxis.css";
8
+
9
+ export class XYAxis extends SVGWidget {
10
+ protected domainAxis: Axis;
11
+ protected valueAxis: Axis;
12
+ protected xAxis: Axis;
13
+ protected yAxis: Axis;
14
+ protected xyBrush;
15
+ protected xBrush;
16
+ protected yBrush;
17
+ protected margin;
18
+ protected focusChart: XYAxis;
19
+
20
+ constructor() {
21
+ super();
22
+ Utility.SimpleSelectionMixin.call(this);
23
+
24
+ this._drawStartPos = "origin";
25
+
26
+ this.domainAxis = new Axis()
27
+ .classed({ domain: true })
28
+ .orientation_default("bottom")
29
+ .type("ordinal")
30
+ .overlapMode_default("stagger")
31
+ .shrinkToFit_default("high")
32
+ .extend_default(0)
33
+ ;
34
+ this.valueAxis = new Axis()
35
+ .classed({ value: true })
36
+ .orientation_default("left")
37
+ .type("linear")
38
+ .shrinkToFit_default("high")
39
+ ;
40
+
41
+ this.xyBrush = d3Brush()
42
+ .on("end", () => {
43
+ return this.brushMoved();
44
+ })
45
+ .on("start.handle brush.handle end.handle", () => {
46
+ return this.brushMoved2();
47
+ })
48
+ ;
49
+ this.xBrush = d3BrushX()
50
+ .on("end", () => {
51
+ return this.brushMoved();
52
+ })
53
+ .on("start.handle brush.handle end.handle", () => {
54
+ return this.brushMoved2();
55
+ })
56
+ ;
57
+ this.yBrush = d3BrushY()
58
+ .on("end", () => {
59
+ return this.brushMoved();
60
+ })
61
+ .on("start.handle brush.handle end.handle", () => {
62
+ return this.brushMoved2();
63
+ })
64
+ ;
65
+ }
66
+
67
+ protected _prevBrush;
68
+ resetSelection() {
69
+ this._prevBrush = null;
70
+ return this;
71
+ }
72
+
73
+ parseData(d) {
74
+ return this.domainAxis.parse(d);
75
+ }
76
+
77
+ parseValue(d) {
78
+ return this.valueAxis.parse(d, true);
79
+ }
80
+
81
+ formatData(d) {
82
+ return this.domainAxis.format(d);
83
+ }
84
+
85
+ formatValue(d) {
86
+ return this.valueAxis.format(d);
87
+ }
88
+
89
+ parsedData() {
90
+ const retVal = this.data().map(function (row) {
91
+ let prevValue = 0;
92
+ return row.map(function (cell, idx) {
93
+ if (idx === 0) {
94
+ return this.parseData(cell);
95
+ }
96
+ if (idx >= this.columns().length) {
97
+ return cell;
98
+ }
99
+ const _retVal = this.yAxisStacked() ? [prevValue, prevValue + this.parseValue(cell)] : this.parseValue(cell);
100
+ prevValue += this.parseValue(cell);
101
+ return _retVal;
102
+ }, this);
103
+ }, this);
104
+ return retVal;
105
+ }
106
+
107
+ bandwidth() {
108
+ return this.domainAxis.bandwidth();
109
+ }
110
+
111
+ protected svg;
112
+ protected svgRegions;
113
+ protected svgDomainGuide;
114
+ protected svgValueGuide;
115
+ protected svgData;
116
+ protected svgDataClipRect;
117
+ protected svgFocus;
118
+ protected svgBrush;
119
+ enter(domNode, element) {
120
+ super.enter(domNode, element);
121
+ this.svg = element.append("g");
122
+ this.svgRegions = element.append("g");
123
+ this.svgDomainGuide = this.svg.append("g");
124
+ this.svgValueGuide = this.svg.append("g");
125
+ this.svgData = this.svg.append("g");
126
+
127
+ this.svgDataClipRect = this.svg.append("clipPath")
128
+ .attr("id", this.id() + "_clippath")
129
+ .append("rect")
130
+ .attr("x", 0)
131
+ .attr("y", 0)
132
+ ;
133
+ this.svgData = this.svg.append("g")
134
+ .attr("clip-path", "url(#" + this.id() + "_clippath)")
135
+ ;
136
+ this._selection.widgetElement(this.svgData);
137
+
138
+ this.svgFocus = element.append("g");
139
+
140
+ this.domainAxis
141
+ .target(this.svg.node())
142
+ .guideTarget(this.svgDomainGuide.node())
143
+ ;
144
+
145
+ this.valueAxis
146
+ .target(this.svg.node())
147
+ .guideTarget(this.svgValueGuide.node())
148
+ ;
149
+
150
+ this.svgBrush = element.append("g")
151
+ .attr("class", "brush")
152
+ ;
153
+ this.chartsEnter(this, this.svgData, 250);
154
+ }
155
+
156
+ resizeBrushHandle(d, width, height) {
157
+ let e;
158
+ let x;
159
+ let y;
160
+ if (d.type === "e" || d.type === "w") {
161
+ e = +(d.type === "e");
162
+ x = e ? 1 : -1;
163
+ y = height / 3;
164
+ return "M" + (0.5 * x) + "," + y +
165
+ "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6) +
166
+ "V" + (2 * y - 6) +
167
+ "A6,6 0 0 " + e + " " + (0.5 * x) + "," + (2 * y) +
168
+ "Z" +
169
+ "M" + (2.5 * x) + "," + (y + 8) +
170
+ "V" + (2 * y - 8) +
171
+ "M" + (4.5 * x) + "," + (y + 8) +
172
+ "V" + (2 * y - 8);
173
+ } else {
174
+ e = +(d.type === "s");
175
+ y = e ? 1 : -1;
176
+ x = width / 3;
177
+ return "M" + x + ", " + (0.5 * y) +
178
+ "A6,6 0 0 " + (e + 1) % 2 + " " + (x + 6) + "," + (6.5 * y) +
179
+ "H" + (2 * x - 6) +
180
+ "A6,6 0 0 " + (e + 1) % 2 + " " + (2 * x) + "," + (0.5 * y) +
181
+ "Z" +
182
+ "M" + (x + 8) + "," + (2.5 * y) +
183
+ "H" + (2 * x - 8) +
184
+ "M" + (x + 8) + "," + (4.5 * y) +
185
+ "H" + (2 * x - 8);
186
+ }
187
+ }
188
+
189
+ private _skipSelection = false;
190
+ skipSelection(): boolean;
191
+ skipSelection(_: boolean): this;
192
+ skipSelection(_?: boolean): boolean | this {
193
+ if (!arguments.length) return this._skipSelection;
194
+ this._skipSelection = _;
195
+ return this;
196
+ }
197
+
198
+ brushMoved() {
199
+ if (this._skipSelection) return;
200
+ let selected = [];
201
+ const context = this;
202
+ const currSel: any = d3BrushSelection(this.svgBrush.node());
203
+ if (currSel) {
204
+ selected = this.data().filter(function (d) {
205
+ const pos = context.dataPos(d[0]);
206
+ if (context.use2dSelection()) {
207
+ const pos2 = context.valuePos(d[1]) + context.valueAxis.bandwidth() / 2;
208
+ return pos >= currSel[0][0] && pos <= currSel[1][0] && pos2 >= currSel[0][1] && pos2 <= currSel[1][1];
209
+ } else {
210
+ return pos >= currSel[0] && pos <= currSel[1];
211
+ }
212
+ });
213
+ }
214
+ this.selection(selected);
215
+ }
216
+
217
+ brushMoved2() {
218
+ const isHorizontal = this.orientation() === "horizontal";
219
+ const handleTypes = this.use2dSelection() ? [] : isHorizontal ? [{ type: "w" }, { type: "e" }] : [{ type: "n" }, { type: "s" }];
220
+ const handlePath = this.svgBrush.selectAll(".handle--custom").data(handleTypes);
221
+ const s = d3Event()?.selection;
222
+ if (s == null) {
223
+ handlePath.attr("display", "none");
224
+ } else if (isHorizontal) {
225
+ handlePath.attr("display", null).attr("transform", (_d, i) => "translate(" + s[i] + "," + 0 + ")");
226
+ } else {
227
+ handlePath.attr("display", null).attr("transform", (_d, i) => "translate(" + 0 + ", " + s[i] + ")");
228
+ }
229
+ }
230
+
231
+ dataPos(d) {
232
+ return this.domainAxis.scalePos(d);
233
+ }
234
+
235
+ valuePos(d) {
236
+ return this.valueAxis.scalePos(d);
237
+ }
238
+
239
+ getAxisSize(host: XYAxis): { width: number, height: number } {
240
+ return {
241
+ width: !this.xAxis ? host.xAxis.width() : this.xAxis.width(),
242
+ height: !this.yAxis ? host.yAxis.width() : this.yAxis.height()
243
+ };
244
+ }
245
+
246
+ calcMargin(_domNode, element, isHorizontal) {
247
+ const margin = {
248
+ top: !isHorizontal && this.selectionMode() ? 10 : 2,
249
+ right: isHorizontal && (this.selectionMode() || this.xAxisFocus()) ? 10 : 2,
250
+ bottom: (this.xAxisFocus() ? this.xAxisFocusHeight() : 0) + 2,
251
+ left: 2
252
+ };
253
+ const width = this.width() - margin.left - margin.right;
254
+ const height = this.height() - margin.top - margin.bottom;
255
+
256
+ let xRight = 0;
257
+ let xHeight = 30;
258
+ let yTop = 0;
259
+ let yWidth = 30;
260
+ for (let i = 0; i < 10; ++i) {
261
+ this.xAxis.width(width - yWidth).height(0);
262
+ const xAxisOverlap = this.xAxis.calcOverflow(element);
263
+ const newXHeight = xAxisOverlap.depth;
264
+
265
+ this.yAxis.width(0).height(height - xHeight);
266
+ const yAxisOverlap = this.yAxis.calcOverflow(element);
267
+ const newYWidth = yAxisOverlap.depth;
268
+
269
+ xRight = xAxisOverlap.right;
270
+ yTop = yAxisOverlap.top;
271
+
272
+ if (newXHeight === xHeight && newYWidth === yWidth) {
273
+ break;
274
+ }
275
+ xHeight = newXHeight;
276
+ yWidth = newYWidth;
277
+ }
278
+ this.xAxis
279
+ .x(width / 2 + yWidth / 2 + margin.left)
280
+ .y(height + margin.top)
281
+ .width(width - yWidth)
282
+ ;
283
+ this.yAxis
284
+ .x(margin.left)
285
+ .y(height / 2 - xHeight / 2 + margin.top)
286
+ .height(height - xHeight)
287
+ ;
288
+ margin.left += yWidth;
289
+ margin.top += yTop;
290
+ margin.right += xRight;
291
+ margin.bottom += xHeight;
292
+ return margin;
293
+ }
294
+
295
+ updateRegions(_domNode, _element, isHorizontal) {
296
+ const context = this;
297
+
298
+ const regions = this.svgRegions.selectAll(".region").data(this.regions());
299
+ regions.enter().append("rect")
300
+ .attr("class", "region")
301
+ ;
302
+ if (isHorizontal) {
303
+ regions
304
+ .attr("x", function (d) { return context.dataPos(d.x0); })
305
+ .attr("y", 0)
306
+ .attr("width", function (d) { return context.dataPos(d.x1) - context.dataPos(d.x0); })
307
+ .attr("height", this.height())
308
+ .style("stroke", function (d) { return context._palette(d.colorID); })
309
+ .style("fill", function (d) { return d3Hsl(context._palette(d.colorID)).brighter(); })
310
+ ;
311
+ } else {
312
+ regions
313
+ .attr("x", 0)
314
+ .attr("y", function (d) { return context.dataPos(d.x0); })
315
+ .attr("width", this.width())
316
+ .attr("height", function (d) { return context.dataPos(d.x0) - context.dataPos(d.x1); })
317
+ .style("stroke", function (d) { return context._palette(d.colorID); })
318
+ .style("fill", function (d) { return d3Hsl(context._palette(d.colorID)).brighter(); })
319
+ ;
320
+ }
321
+ regions.exit().remove();
322
+ }
323
+
324
+ protected _prevXAxisType;
325
+ update(domNode, element) {
326
+ this.selectionGlow(!this.tabNavigation());
327
+ super.update(domNode, element);
328
+ const context = this;
329
+
330
+ const isHorizontal = this.orientation() === "horizontal";
331
+ this.updateRegions(domNode, element, isHorizontal);
332
+
333
+ this.domainAxis
334
+ .orientation(isHorizontal ? "bottom" : "left")
335
+ .title(this.xAxisTitle_exists() ? this.xAxisTitle() : this.columns()[0])
336
+ ;
337
+ this.valueAxis
338
+ .orientation(isHorizontal ? "left" : "bottom")
339
+ ;
340
+ this.xAxis = isHorizontal ? this.domainAxis : this.valueAxis;
341
+ this.yAxis = isHorizontal ? this.valueAxis : this.domainAxis;
342
+
343
+ // Update Domain ---
344
+ switch (this.xAxisType()) {
345
+ case "ordinal":
346
+ const colLen = this.columns().length;
347
+ const ordinalMappings = {};
348
+ this.domainAxis
349
+ .ordinals(this.data().map(function (d) {
350
+ ordinalMappings[d[0]] = context.xAxisOrdinalMapping(d, d[colLen]);
351
+ return d[0];
352
+ }))
353
+ .ordinalMappings(ordinalMappings)
354
+ ;
355
+
356
+ break;
357
+ default:
358
+ const domainMin = this.xAxisDomainLow() ? this.xAxisDomainLow() : this.domainAxis.parseInvert(d3Min(this.parsedData(), function (data) {
359
+ return data[0];
360
+ }));
361
+ const domainMax = this.xAxisDomainHigh() ? this.xAxisDomainHigh() : this.domainAxis.parseInvert(d3Max(this.parsedData(), function (data) {
362
+ return data[0];
363
+ }));
364
+ if (domainMin !== undefined && domainMax !== undefined) {
365
+ this.domainAxis
366
+ .low(domainMin)
367
+ .high(domainMax)
368
+ ;
369
+ }
370
+ break;
371
+ }
372
+
373
+ const min = this.yAxisDomainLow() ? this.yAxisDomainLow() : this.valueAxis.parseInvert(d3Min(this.parsedData(), function (data: any[]) {
374
+ return d3Min(data.filter(function (cell, i) { return i > 0 && context.columns()[i] && context.columns()[i].indexOf("__") !== 0 && cell !== null; }), function (d) { return d instanceof Array ? d[0] : d; });
375
+ }));
376
+ const max = this.yAxisDomainHigh() ? this.yAxisDomainHigh() : this.valueAxis.parseInvert(d3Max(this.parsedData(), function (data: any[]) {
377
+ return d3Max(data.filter(function (cell, i) { return i > 0 && context.columns()[i] && context.columns()[i].indexOf("__") !== 0 && cell !== null; }), function (d) { return d instanceof Array ? d[1] : d; });
378
+ }));
379
+ this.valueAxis
380
+ .low(min)
381
+ .high(max)
382
+ ;
383
+
384
+ // Calculate Margins ---
385
+ this.margin = this.calcMargin(domNode, element, isHorizontal);
386
+
387
+ // Update Range ---
388
+ let width = this.width() - this.margin.left - this.margin.right;
389
+ if (width < 0) width = 0;
390
+ let height = this.height() - this.margin.top - this.margin.bottom;
391
+ if (height < 0) height = 0;
392
+ const maxCurrExtent = isHorizontal ? width : height;
393
+ const maxOtherExtent = isHorizontal ? height : width;
394
+
395
+ // Render ---
396
+ this.domainAxis
397
+ .tickLength(this.xAxisGuideLines() ? maxOtherExtent : 0)
398
+ .render()
399
+ ;
400
+ this.valueAxis
401
+ .tickLength(this.yAxisGuideLines() ? maxCurrExtent : 0)
402
+ .render()
403
+ ;
404
+
405
+ this.svgDataClipRect
406
+ .attr("width", width)
407
+ .attr("height", height)
408
+ ;
409
+ this.svgData.transition()
410
+ .attr("transform", "translate(" + this.margin.left + "," + this.margin.top + ")")
411
+ ;
412
+
413
+ this.updateBrush(width, height, maxCurrExtent, isHorizontal);
414
+ this.updateFocusChart(domNode, element, this.margin, width, height, isHorizontal);
415
+ this.chartsUpdate(width, height, 250);
416
+ if (this.selectionMode()) {
417
+ return this.brushMoved();
418
+ }
419
+ }
420
+
421
+ updateBrush(width, height, maxCurrExtent, isHorizontal) {
422
+ const currBrush = this.use2dSelection() ? this.xyBrush : isHorizontal ? this.xBrush : this.yBrush;
423
+ const prevBrushSel: any = d3BrushSelection(this.svgBrush.node());
424
+ currBrush.extent([[0, 0], [width, height]]);
425
+ this.svgBrush
426
+ .attr("transform", "translate(" + this.margin.left + ", " + this.margin.top + ")")
427
+ .style("display", this.selectionMode() ? null : "none")
428
+ .call(currBrush)
429
+ ;
430
+ const handleTypes = this.use2dSelection() ? [] : isHorizontal ? [{ type: "w" }, { type: "e" }] : [{ type: "n" }, { type: "s" }];
431
+ const handlePath = this.svgBrush.selectAll(".handle--custom").data(handleTypes);
432
+ handlePath.enter().append("path")
433
+ .attr("class", "handle--custom")
434
+ .merge(handlePath)
435
+ .attr("cursor", isHorizontal ? "ew-resize" : "ns-resize")
436
+ .attr("d", (d) => this.resizeBrushHandle(d, width, height))
437
+ ;
438
+
439
+ if (this.selectionMode()) {
440
+ if (this._prevXAxisType !== this.xAxisType()) {
441
+ this._prevXAxisType = this.xAxisType();
442
+ this._prevBrush = null;
443
+ }
444
+ if (this._prevBrush) {
445
+ if (prevBrushSel) {
446
+ if (this._prevBrush.orientation !== this.orientation()) {
447
+ const tmp = prevBrushSel[0];
448
+ prevBrushSel[0] = this._prevBrush.maxCurrExtent - prevBrushSel[1];
449
+ prevBrushSel[1] = this._prevBrush.maxCurrExtent - tmp;
450
+ }
451
+ const ratio = maxCurrExtent / this._prevBrush.maxCurrExtent;
452
+ if (ratio !== 1) {
453
+ this.svgBrush.transition()
454
+ .on("start", function () {
455
+ currBrush.on("end", null);
456
+ })
457
+ .call(currBrush.move, [prevBrushSel[0] * ratio, prevBrushSel[1] * ratio])
458
+ .on("end", () => {
459
+ currBrush.on("end", () => {
460
+ return this.brushMoved();
461
+ });
462
+ })
463
+ ;
464
+ }
465
+ }
466
+ } else {
467
+ this.svgBrush
468
+ .call(currBrush.move, [0, maxCurrExtent])
469
+ ;
470
+ }
471
+ this._prevBrush = {
472
+ orientation: this.orientation(),
473
+ maxCurrExtent
474
+ };
475
+ }
476
+ }
477
+
478
+ updateFocusChart(domNode, element, margin, width, height, isHorizontal) {
479
+ const context: XYAxis = this;
480
+ const focusChart = this.svgFocus.selectAll("#" + this.id() + "_focusChart").data(this.xAxisFocus() ? [true] : []);
481
+ focusChart.enter().append("g")
482
+ .attr("id", this.id() + "_focusChart")
483
+ .attr("class", "focus")
484
+ .each(function () {
485
+ context.focusChart = new (context.constructor as any)()
486
+ .target(this)
487
+ ;
488
+ context.focusChart.xBrush
489
+ .on("brush.focus", function () {
490
+ context.syncAxis(width);
491
+ context.chartsUpdate(width, height, 0);
492
+ })
493
+ ;
494
+ context.focusChart
495
+ .layers(context.layers().map((w: any) => new w.constructor()))
496
+ ;
497
+ })
498
+ .merge(focusChart)
499
+ .each(function (this: SVGElement) {
500
+ context.copyPropsTo(context.focusChart, ["layers"]);
501
+ let layerIdx = 0;
502
+ for (const layer of context.layers()) {
503
+ layer.copyPropsTo(context.focusChart.layers()[layerIdx]);
504
+ layerIdx++;
505
+ }
506
+ context.focusChart
507
+ .xAxisFocus(false)
508
+ .selectionMode(true)
509
+ .skipSelection(true)
510
+ .orientation("horizontal")
511
+ .xAxisGuideLines(false)
512
+ .xAxisDomainLow(null)
513
+ .xAxisDomainHigh(null)
514
+ .yAxisGuideLines(false)
515
+ .x(context.width() / 2)
516
+ .y(context.height() - context.xAxisFocusHeight() / 2)
517
+ .width(context.width())
518
+ .height(context.xAxisFocusHeight())
519
+ .columns(context.columns())
520
+ .data(context.data())
521
+ .render()
522
+ ;
523
+ context.syncAxis(width);
524
+ })
525
+ ;
526
+ focusChart.exit()
527
+ .each(function () {
528
+ if (context.focusChart) {
529
+ context.focusChart
530
+ .target(null)
531
+ ;
532
+ delete context.focusChart;
533
+ }
534
+ })
535
+ .remove()
536
+ ;
537
+ }
538
+
539
+ syncAxis(width: number) {
540
+ const currSel = d3BrushSelection(this.focusChart.svgBrush.node()) as [number, number];
541
+ if (currSel) {
542
+ if (this.focusChart.xAxisType() !== "ordinal") {
543
+ this.xAxis.domain([this.focusChart.xAxis.invert(currSel[0]), this.focusChart.xAxis.invert(currSel[1])]);
544
+ } else {
545
+ const brushWidth = currSel[1] - currSel[0];
546
+ const scale = brushWidth / width;
547
+ this.xAxis.range([-currSel[0] / scale, (width - currSel[0]) / scale]);
548
+ }
549
+ this.xAxis.rerender();
550
+ }
551
+ }
552
+
553
+ // Layers ---
554
+ layerColumns(host: XYAxis): string[] {
555
+ const masterColumns = host.columns();
556
+ const retVal = super.columns().filter(col => col !== masterColumns[0]);
557
+ if (!retVal.length) {
558
+ return masterColumns;
559
+ }
560
+ return [masterColumns[0], ...retVal];
561
+ }
562
+
563
+ layerColumnIndices(host: XYAxis): number[] {
564
+ const masterColumns = host.columns();
565
+ const layerColumns = this.layerColumns(host);
566
+ return layerColumns.map(col => masterColumns.indexOf(col));
567
+ }
568
+
569
+ layerColumnIndex(host: XYAxis, column: string): number {
570
+ const masterColumns = host.columns();
571
+ return masterColumns.indexOf(column);
572
+ }
573
+
574
+ layerData(host?: XYAxis): any[][] {
575
+ if (arguments.length === 1) {
576
+ const indices = this.layerColumnIndices(host);
577
+ return host.data().map(row => {
578
+ const retVal = indices.map(idx => row[idx]);
579
+ (retVal as any).__hpcc_origRow = row;
580
+ return retVal;
581
+ });
582
+ }
583
+ throw new Error("Setting data on XYAxisLayer is not supported.");
584
+ }
585
+
586
+ layerEnter(host: XYAxis, element, duration: number = 250) {
587
+ }
588
+
589
+ layerUpdate(host: XYAxis, element, duration: number = 250) {
590
+ }
591
+
592
+ layerExit(host: XYAxis, element, duration: number = 250) {
593
+ }
594
+
595
+ chartsEnter(host: XYAxis, element, duration: number = 250) {
596
+ this.layerEnter(this, element, duration);
597
+ for (const w of this.layers()) {
598
+ w["__xyAxisElement"] = element.append("g")
599
+ .attr("class", w.class())
600
+ ;
601
+ w
602
+ .target(w["__xyAxisElement"].node() as SVGElement)
603
+ .layerEnter(this, element, duration)
604
+ ;
605
+ }
606
+ }
607
+
608
+ chartsUpdate(width, height, duration): void {
609
+ this.layerUpdate(this, this.svgData, duration);
610
+ for (const w of this.layers()) {
611
+ w
612
+ .resize({ width, height })
613
+ .layerUpdate(this, w["__xyAxisElement"], duration)
614
+ ;
615
+ }
616
+ }
617
+
618
+ exit(domNode, element) {
619
+ this.valueAxis.target(null);
620
+ this.domainAxis.target(null);
621
+ super.exit(domNode, element);
622
+ }
623
+
624
+ selection(_selected) {
625
+ const context = this;
626
+ this._selection.widgetElement().selectAll(".selected,.deselected")
627
+ .each(function (d) {
628
+ const selected = _selected.indexOf(d.origRow) >= 0;
629
+ d3Select(this)
630
+ .classed("selected", selected)
631
+ .classed("deselected", !selected)
632
+ .attr("filter", context._selection.svgGlowID() && selected ? `url(#${context._selection.svgGlowID()})` : null)
633
+ ;
634
+ })
635
+ ;
636
+
637
+ const selRows = _selected.map(d => {
638
+ return this.rowToObj(d);
639
+ });
640
+ setTimeout(() => {
641
+ this.click(selRows, "", true);
642
+ }, 0);
643
+ }
644
+
645
+ // XYAxis ---
646
+ xAxisOrdinalMapping(origRow, lparam) {
647
+ return origRow[0];
648
+ }
649
+
650
+ // Events ---
651
+ click(row, column, selected) {
652
+ // console.log("Click: " + JSON.stringify(row) + ", " + column + ", " + selected);
653
+ }
654
+
655
+ // Selection ---
656
+ _selection: Utility.SimpleSelection;
657
+ }
658
+ XYAxis.prototype._class += " chart_XYAxis";
659
+ XYAxis.prototype.mixin(Utility.SimpleSelectionMixin);
660
+
661
+ export interface XYAxis {
662
+ _palette;
663
+ orientation(): "horizontal" | "vertical";
664
+ orientation(_: "horizontal" | "vertical"): this;
665
+ orientation_default(_: string);
666
+ pointSizeColumn(): string;
667
+ pointSizeColumn(_: string): this;
668
+ pointSizeColumn_exists(): boolean;
669
+ minPointSize(): number;
670
+ minPointSize(_: number): this;
671
+ maxPointSize(): number;
672
+ maxPointSize(_: number): this;
673
+ use2dSelection(): boolean;
674
+ use2dSelection(_: boolean): this;
675
+ selectionMode(): boolean;
676
+ selectionMode(_: boolean): this;
677
+ xAxisTitle(): string;
678
+ xAxisTitle(_: string): this;
679
+ xAxisTitle_exists(): boolean;
680
+ xAxisTickCount(): number;
681
+ xAxisTickCount(_: number): this;
682
+ xAxisTickFormat(): string;
683
+ xAxisTickFormat(_: string): this;
684
+ xAxisTicks(): Array<{ value: string, label: string }>;
685
+ xAxisTicks(_: Array<{ value: string, label: string }>): this;
686
+ xAxisType(): "none" | "ordinal" | "linear" | "pow" | "log" | "time";
687
+ xAxisType(_: "none" | "ordinal" | "linear" | "pow" | "log" | "time"): this;
688
+ xAxisType_default(_: string);
689
+ xAxisTypeTimePattern(): string;
690
+ xAxisTypeTimePattern(_: string): this;
691
+ xAxisDomainLow(): number | string;
692
+ xAxisDomainLow(_: number | string): this;
693
+ xAxisDomainHigh(): number | string;
694
+ xAxisDomainHigh(_: number | string): this;
695
+ xAxisFontSize(): number | string;
696
+ xAxisFontSize(_: number | string): this;
697
+ xAxisFontFamily(): string;
698
+ xAxisFontFamily(_: string): this;
699
+ xAxisOrdinalPaddingInner(): number;
700
+ xAxisOrdinalPaddingInner(_: number): this;
701
+ xAxisOrdinalPaddingOuter(): number;
702
+ xAxisOrdinalPaddingOuter(_: number): this;
703
+ xAxisOverlapMode(): "none" | "stagger" | "hide" | "rotate" | "linebreak" | "wrap";
704
+ xAxisOverlapMode(_: "none" | "stagger" | "hide" | "rotate" | "linebreak" | "wrap"): this;
705
+ xAxisLabelRotation(): number;
706
+ xAxisLabelRotation(_: number): this;
707
+ xAxisDomainPadding(): number;
708
+ xAxisDomainPadding(_: number): this;
709
+ xAxisGuideLines(): boolean;
710
+ xAxisGuideLines(_: boolean): this;
711
+ xAxisGuideLines_default(_: boolean);
712
+ xAxisFocus(): boolean;
713
+ xAxisFocus(_: boolean): this;
714
+ xAxisFocusHeight(): number;
715
+ xAxisFocusHeight(_: number): this;
716
+ xAxisHidden(): boolean;
717
+ xAxisHidden(_: boolean): this;
718
+ xAxisHidden_default(_: boolean);
719
+ yAxisTitle(): string;
720
+ yAxisTitle(_: string): this;
721
+ yAxisTickCount(): number;
722
+ yAxisTickCount(_: number): this;
723
+ yAxisTickFormat(): string;
724
+ yAxisTickFormat(_: string): this;
725
+ yAxisTicks(): Array<{ value: string, label: string }>;
726
+ yAxisTicks(_: Array<{ value: string, label: string }>): this;
727
+ yAxisType(): "none" | "ordinal" | "linear" | "pow" | "log" | "time";
728
+ yAxisType(_: "none" | "ordinal" | "linear" | "pow" | "log" | "time"): this;
729
+ yAxisType_default(_: string);
730
+ yAxisTypeTimePattern(): string;
731
+ yAxisTypeTimePattern(_: string): this;
732
+ yAxisTypePowExponent(): number;
733
+ yAxisTypePowExponent(_: number): this;
734
+ yAxisTypeLogBase(): number;
735
+ yAxisTypeLogBase(_: number): this;
736
+ yAxisStacked(): boolean;
737
+ yAxisStacked(_: boolean): this;
738
+ yAxisDomainLow(): number | string;
739
+ yAxisDomainLow(_: number | string): this;
740
+ yAxisDomainHigh(): number | string;
741
+ yAxisDomainHigh(_: number | string): this;
742
+ yAxisDomainPadding(): number;
743
+ yAxisDomainPadding(_: number): this;
744
+ yAxisGuideLines(): boolean;
745
+ yAxisGuideLines(_: boolean): this;
746
+ yAxisGuideLines_default(_: boolean);
747
+ yAxisHidden(): boolean;
748
+ yAxisHidden(_: boolean): this;
749
+ yAxisHidden_default(_: boolean);
750
+ regions(): object[];
751
+ regions(_: object[]): this;
752
+ layers(): XYAxis[];
753
+ layers(_: XYAxis[]): this;
754
+ xAxisPadding(): number;
755
+ xAxisPadding(_: number): this;
756
+ yAxisPadding(): number;
757
+ yAxisPadding(_: number): this;
758
+
759
+ // Tab Navigation
760
+ tabNavigation(): boolean;
761
+ tabNavigation(_: boolean): this;
762
+ }
763
+
764
+ XYAxis.prototype.publish("orientation", "horizontal", "set", "Selects orientation for the axis", ["horizontal", "vertical"]);
765
+ XYAxis.prototype.publish("pointSizeColumn", null, "string", "pointSizeColumn", null, { optional: true });
766
+ XYAxis.prototype.publish("minPointSize", 6, "number", "minPointSize");
767
+ XYAxis.prototype.publish("maxPointSize", 26, "number", "maxPointSize");
768
+ XYAxis.prototype.publish("use2dSelection", false, "boolean", "2D Range Selector");
769
+ XYAxis.prototype.publish("selectionMode", false, "boolean", "Range Selector");
770
+ XYAxis.prototype.publishProxy("xAxisTitle", "domainAxis", "title");
771
+ XYAxis.prototype.publishProxy("xAxisTickCount", "domainAxis", "tickCount");
772
+ XYAxis.prototype.publishProxy("xAxisTickFormat", "domainAxis", "tickFormat");
773
+ XYAxis.prototype.publishProxy("xAxisTicks", "domainAxis", "ticks");
774
+ XYAxis.prototype.publishProxy("xAxisType", "domainAxis", "type");
775
+ XYAxis.prototype.publishProxy("xAxisTypeTimePattern", "domainAxis", "timePattern");
776
+ XYAxis.prototype.publish("xAxisDomainLow", null, "string", "X-Axis Low", null, { optional: true, disable: (w: XYAxis) => w.xAxisType() === "ordinal" });
777
+ XYAxis.prototype.publish("xAxisDomainHigh", null, "string", "X-Axis High", null, { optional: true, disable: (w: XYAxis) => w.xAxisType() === "ordinal" });
778
+ XYAxis.prototype.publishProxy("xAxisFontSize", "domainAxis", "fontSize");
779
+ XYAxis.prototype.publishProxy("xAxisFontFamily", "domainAxis", "fontFamily");
780
+ XYAxis.prototype.publishProxy("xAxisOrdinalPaddingInner", "domainAxis", "ordinalPaddingInner");
781
+ XYAxis.prototype.publishProxy("xAxisOrdinalPaddingOuter", "domainAxis", "ordinalPaddingOuter");
782
+ XYAxis.prototype.publishProxy("xAxisOverlapMode", "domainAxis", "overlapMode");
783
+ XYAxis.prototype.publishProxy("xAxisLabelRotation", "domainAxis", "labelRotation");
784
+ XYAxis.prototype.publishProxy("xAxisDomainPadding", "domainAxis", "extend");
785
+ XYAxis.prototype.publish("xAxisGuideLines", false, "boolean", "Y-Axis Guide Lines");
786
+ XYAxis.prototype.publish("xAxisFocus", false, "boolean", "X-Axis Focus", null, { disable: (w: any) => w.orientation() !== "horizontal" });
787
+ XYAxis.prototype.publish("xAxisFocusHeight", 80, "number", "X-Axis Focus Height", null, { disable: (w: any) => !w.xAxisFocus() });
788
+ XYAxis.prototype.publishProxy("xAxisHidden", "domainAxis", "hidden");
789
+ XYAxis.prototype.publishProxy("yAxisFontSize", "valueAxis", "fontSize");
790
+ XYAxis.prototype.publishProxy("yAxisFontFamily", "valueAxis", "fontFamily");
791
+ XYAxis.prototype.publishProxy("yAxisTitle", "valueAxis", "title");
792
+ XYAxis.prototype.publishProxy("yAxisTickCount", "valueAxis", "tickCount");
793
+ XYAxis.prototype.publishProxy("yAxisTickFormat", "valueAxis", "tickFormat");
794
+ XYAxis.prototype.publishProxy("yAxisTicks", "valueAxis", "ticks");
795
+ XYAxis.prototype.publishProxy("yAxisType", "valueAxis", "type");
796
+ XYAxis.prototype.publishProxy("yAxisTypeTimePattern", "valueAxis", "timePattern");
797
+ XYAxis.prototype.publishProxy("yAxisTypePowExponent", "valueAxis", "powExponent");
798
+ XYAxis.prototype.publishProxy("yAxisTypeLogBase", "valueAxis", "logBase");
799
+ XYAxis.prototype.publish("yAxisStacked", false, "boolean", "Stacked Chart", null, { tags: ["Basic"], disable: (w: any) => w.xAxisType() !== "ordinal" || w._class.indexOf("chart_Column") < 0 });
800
+ XYAxis.prototype.publish("yAxisDomainLow", null, "string", "Y-Axis Low", null, { optional: true, disable: (w: any) => w.yAxisType() === "ordinal" });
801
+ XYAxis.prototype.publish("yAxisDomainHigh", null, "string", "Y-Axis High", null, { optional: true, disable: (w: any) => w.yAxisType() === "ordinal" });
802
+ XYAxis.prototype.publishProxy("yAxisDomainPadding", "valueAxis", "extend");
803
+ XYAxis.prototype.publish("yAxisGuideLines", true, "boolean", "Y-Axis Guide Lines");
804
+ XYAxis.prototype.publishProxy("yAxisHidden", "valueAxis", "hidden");
805
+ XYAxis.prototype.publish("regions", [], "array", "Regions");
806
+ XYAxis.prototype.publish("layers", [], "widgetArray", "Layers", null, { render: false });
807
+ XYAxis.prototype.publishProxy("xAxisPadding", "domainAxis", "padding");
808
+ XYAxis.prototype.publishProxy("yAxisPadding", "valueAxis", "padding");
809
+ XYAxis.prototype.publish("tabNavigation", false, "boolean", "Enable or disable tab navigation");