@hpcc-js/chart 3.7.1 → 3.7.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +43 -43
- package/README.md +93 -93
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/index.umd.cjs +1 -1
- package/dist/index.umd.cjs.map +1 -1
- package/package.json +6 -6
- package/src/Area.md +176 -176
- package/src/Area.ts +12 -12
- package/src/Axis.css +35 -35
- package/src/Axis.ts +781 -781
- package/src/Bar.md +90 -90
- package/src/Bar.ts +9 -9
- package/src/Bubble.css +16 -16
- package/src/Bubble.md +69 -69
- package/src/Bubble.ts +196 -196
- package/src/BubbleXY.ts +14 -14
- package/src/Bullet.css +59 -59
- package/src/Bullet.md +104 -104
- package/src/Bullet.ts +176 -176
- package/src/Column.css +44 -44
- package/src/Column.md +90 -90
- package/src/Column.ts +684 -684
- package/src/Contour.md +88 -88
- package/src/Contour.ts +97 -97
- package/src/D3Cloud.ts +403 -403
- package/src/Gantt.md +119 -119
- package/src/Gantt.ts +14 -14
- package/src/Gauge.md +148 -148
- package/src/Gauge.ts +368 -368
- package/src/HalfPie.md +62 -62
- package/src/HalfPie.ts +26 -26
- package/src/Heat.md +42 -42
- package/src/Heat.ts +283 -283
- package/src/HexBin.css +8 -8
- package/src/HexBin.md +88 -88
- package/src/HexBin.ts +144 -144
- package/src/Line.css +4 -4
- package/src/Line.md +170 -170
- package/src/Line.ts +14 -14
- package/src/Pie.css +50 -50
- package/src/Pie.md +88 -88
- package/src/Pie.ts +546 -546
- package/src/QuarterPie.md +61 -61
- package/src/QuarterPie.ts +35 -35
- package/src/QuartileCandlestick.md +129 -129
- package/src/QuartileCandlestick.ts +349 -349
- package/src/Radar.css +14 -14
- package/src/Radar.md +104 -104
- package/src/Radar.ts +336 -336
- package/src/RadialBar.css +25 -25
- package/src/RadialBar.md +91 -91
- package/src/RadialBar.ts +217 -217
- package/src/Scatter.css +42 -42
- package/src/Scatter.md +163 -163
- package/src/Scatter.ts +412 -412
- package/src/StatChart.md +117 -117
- package/src/StatChart.ts +261 -261
- package/src/Step.md +163 -163
- package/src/Step.ts +12 -12
- package/src/Summary.css +55 -55
- package/src/Summary.md +219 -219
- package/src/Summary.ts +322 -322
- package/src/SummaryC.md +154 -154
- package/src/SummaryC.ts +240 -240
- package/src/WordCloud.css +2 -2
- package/src/WordCloud.md +144 -144
- package/src/WordCloud.ts +268 -268
- package/src/XYAxis.css +40 -40
- package/src/XYAxis.md +149 -149
- package/src/XYAxis.ts +809 -809
- package/src/__package__.ts +3 -3
- package/src/__tests__/heat.ts +71 -71
- package/src/__tests__/index.ts +3 -3
- package/src/__tests__/pie.ts +20 -20
- package/src/__tests__/stat.ts +16 -16
- package/src/__tests__/test3.ts +68 -68
- package/src/index.ts +28 -28
- package/src/test.ts +70 -70
- package/src/timeFormats.ts +26 -26
|
@@ -1,349 +1,349 @@
|
|
|
1
|
-
import { SVGWidget } from "@hpcc-js/common";
|
|
2
|
-
import { scaleLinear as d3ScaleLinear } from "d3-scale";
|
|
3
|
-
|
|
4
|
-
export class QuartileCandlestick extends SVGWidget {
|
|
5
|
-
protected _g;
|
|
6
|
-
protected _leftLine;
|
|
7
|
-
protected _rightLine;
|
|
8
|
-
protected _midLine;
|
|
9
|
-
protected _midOuterRect;
|
|
10
|
-
protected _midInnerRect1;
|
|
11
|
-
protected _midInnerRect2;
|
|
12
|
-
protected _q0text;
|
|
13
|
-
protected _q1text;
|
|
14
|
-
protected _q2text;
|
|
15
|
-
protected _q3text;
|
|
16
|
-
protected _q4text;
|
|
17
|
-
protected _q0val;
|
|
18
|
-
protected _q1val;
|
|
19
|
-
protected _q2val;
|
|
20
|
-
protected _q3val;
|
|
21
|
-
protected _q4val;
|
|
22
|
-
constructor() {
|
|
23
|
-
super();
|
|
24
|
-
}
|
|
25
|
-
enter(domNode, element) {
|
|
26
|
-
super.enter(domNode, element);
|
|
27
|
-
this._g = element.append("g");
|
|
28
|
-
this._leftLine = this._g.append("rect");
|
|
29
|
-
this._rightLine = this._g.append("rect");
|
|
30
|
-
this._midLine = this._g.append("rect");
|
|
31
|
-
this._midOuterRect = this._g.append("rect");
|
|
32
|
-
this._midInnerRect1 = this._g.append("rect");
|
|
33
|
-
this._midInnerRect2 = this._g.append("rect");
|
|
34
|
-
this._q0text = this._g.append("text");
|
|
35
|
-
this._q1text = this._g.append("text");
|
|
36
|
-
this._q2text = this._g.append("text");
|
|
37
|
-
this._q3text = this._g.append("text");
|
|
38
|
-
this._q4text = this._g.append("text");
|
|
39
|
-
this._q0val = this._g.append("text");
|
|
40
|
-
this._q1val = this._g.append("text");
|
|
41
|
-
this._q2val = this._g.append("text");
|
|
42
|
-
this._q3val = this._g.append("text");
|
|
43
|
-
this._q4val = this._g.append("text");
|
|
44
|
-
}
|
|
45
|
-
update(domNode, element) {
|
|
46
|
-
super.update(domNode, element);
|
|
47
|
-
const valueSize = (this.orientation() === "horizontal" ? this.width() : this.height()) - this.lineWidth();
|
|
48
|
-
const domainSize = this.orientation() === "horizontal" ? this.height() : this.width();
|
|
49
|
-
const scale = d3ScaleLinear()
|
|
50
|
-
.domain([
|
|
51
|
-
this.data()[0],
|
|
52
|
-
this.data()[4]
|
|
53
|
-
])
|
|
54
|
-
.range([
|
|
55
|
-
this.edgePadding(),
|
|
56
|
-
valueSize - this.edgePadding()
|
|
57
|
-
])
|
|
58
|
-
;
|
|
59
|
-
const candleWidth = this.candleWidth_exists() ? this.candleWidth() : domainSize;
|
|
60
|
-
const lineWidth = this.lineWidth();
|
|
61
|
-
const lineColor = this.lineColor();
|
|
62
|
-
const roundedCorners = this.roundedCorners();
|
|
63
|
-
const q0x = this.edgePadding();
|
|
64
|
-
let q1x = scale(this.data()[1]);
|
|
65
|
-
let q2x = scale(this.data()[2]);
|
|
66
|
-
let q3x = scale(this.data()[3]);
|
|
67
|
-
const dataTop = -candleWidth / 2;
|
|
68
|
-
const dataBottom = candleWidth / 2;
|
|
69
|
-
const upperTextRotation = this.upperTextRotation();
|
|
70
|
-
const lowerTextRotation = this.lowerTextRotation();
|
|
71
|
-
const padding = this.textPadding();
|
|
72
|
-
const labelFontSize = this.labelFontSize();
|
|
73
|
-
const valueFontSize = this.valueFontSize();
|
|
74
|
-
const sz = Math.max(labelFontSize, valueFontSize);
|
|
75
|
-
const q4x = valueSize - q0x;
|
|
76
|
-
if (sz > 0) {
|
|
77
|
-
while (q1x - q0x < sz) {
|
|
78
|
-
q1x += sz;
|
|
79
|
-
}
|
|
80
|
-
while (q2x - q1x < sz) {
|
|
81
|
-
q2x += sz;
|
|
82
|
-
}
|
|
83
|
-
while (q3x - q2x < sz) {
|
|
84
|
-
q3x += sz;
|
|
85
|
-
}
|
|
86
|
-
while (q4x - q3x < sz) {
|
|
87
|
-
q3x -= sz;
|
|
88
|
-
}
|
|
89
|
-
while (q3x - q2x < sz) {
|
|
90
|
-
q2x -= sz;
|
|
91
|
-
}
|
|
92
|
-
while (q2x - q1x < sz) {
|
|
93
|
-
q1x -= sz;
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
let transX = (-valueSize / 2) - (this.lineWidth() / 2);
|
|
97
|
-
let transY = 0;
|
|
98
|
-
let rotate = 0;
|
|
99
|
-
const s = 1;
|
|
100
|
-
let textScale = 1;
|
|
101
|
-
let labelAnchor = "start";
|
|
102
|
-
let valueAnchor = "end";
|
|
103
|
-
if (this.orientation() === "vertical") {
|
|
104
|
-
transX = 0;
|
|
105
|
-
transY = valueSize / 2 + (this.lineWidth() / 2);
|
|
106
|
-
rotate = -90;
|
|
107
|
-
labelAnchor = "end";
|
|
108
|
-
valueAnchor = "start";
|
|
109
|
-
textScale = -1;
|
|
110
|
-
}
|
|
111
|
-
this._g
|
|
112
|
-
.style("shape-rendering", "crispEdges")
|
|
113
|
-
.attr("transform", `translate(${transX},${transY})rotate(${rotate})scale(${s})`)
|
|
114
|
-
;
|
|
115
|
-
this._leftLine
|
|
116
|
-
.attr("fill", lineColor)
|
|
117
|
-
.attr("height", candleWidth)
|
|
118
|
-
.attr("width", lineWidth)
|
|
119
|
-
.attr("x", q0x)
|
|
120
|
-
.attr("y", dataTop)
|
|
121
|
-
.attr("rx", roundedCorners)
|
|
122
|
-
.attr("ry", roundedCorners)
|
|
123
|
-
;
|
|
124
|
-
this._rightLine
|
|
125
|
-
.attr("class", "right-line")
|
|
126
|
-
.attr("fill", lineColor)
|
|
127
|
-
.attr("height", candleWidth)
|
|
128
|
-
.attr("width", lineWidth)
|
|
129
|
-
.attr("x", q4x)
|
|
130
|
-
.attr("y", dataTop)
|
|
131
|
-
.attr("rx", roundedCorners)
|
|
132
|
-
.attr("ry", roundedCorners)
|
|
133
|
-
;
|
|
134
|
-
this._midLine
|
|
135
|
-
.attr("fill", lineColor)
|
|
136
|
-
.attr("height", lineWidth)
|
|
137
|
-
.attr("width", q4x - q0x)
|
|
138
|
-
.attr("x", q0x)
|
|
139
|
-
.attr("y", -lineWidth / 2)
|
|
140
|
-
;
|
|
141
|
-
this._midOuterRect
|
|
142
|
-
.attr("fill", lineColor)
|
|
143
|
-
.attr("height", candleWidth)
|
|
144
|
-
.attr("width", q3x - q1x)
|
|
145
|
-
.attr("x", q1x)
|
|
146
|
-
.attr("y", dataTop)
|
|
147
|
-
.attr("rx", roundedCorners)
|
|
148
|
-
.attr("ry", roundedCorners)
|
|
149
|
-
;
|
|
150
|
-
this._midInnerRect1
|
|
151
|
-
.attr("fill", this.innerRectColor())
|
|
152
|
-
.attr("height", candleWidth - (lineWidth * 2))
|
|
153
|
-
.attr("width", q2x - (q1x + (lineWidth * 2)))
|
|
154
|
-
.attr("x", q1x + lineWidth)
|
|
155
|
-
.attr("y", lineWidth - (candleWidth / 2))
|
|
156
|
-
.attr("rx", roundedCorners * 0.618)
|
|
157
|
-
.attr("ry", roundedCorners * 0.618)
|
|
158
|
-
;
|
|
159
|
-
this._midInnerRect2
|
|
160
|
-
.attr("fill", this.innerRectColor())
|
|
161
|
-
.attr("height", candleWidth - (lineWidth * 2))
|
|
162
|
-
.attr("width", q3x - q2x - lineWidth)
|
|
163
|
-
.attr("x", q2x)
|
|
164
|
-
.attr("y", lineWidth - (candleWidth / 2))
|
|
165
|
-
.attr("rx", roundedCorners * 0.618)
|
|
166
|
-
.attr("ry", roundedCorners * 0.618)
|
|
167
|
-
;
|
|
168
|
-
this._q0text
|
|
169
|
-
.attr("height", candleWidth)
|
|
170
|
-
.attr("width", q3x - q1x)
|
|
171
|
-
.attr("display", this.showLabels() ? null : "none")
|
|
172
|
-
.attr("fill", this.textColor())
|
|
173
|
-
.attr("x", 0)
|
|
174
|
-
.attr("y", 0)
|
|
175
|
-
.attr("transform", `translate(${q0x}, ${dataTop - padding})rotate(${upperTextRotation})scale(${textScale})`)
|
|
176
|
-
.attr("font-size", labelFontSize)
|
|
177
|
-
.attr("text-anchor", labelAnchor)
|
|
178
|
-
.attr("alignment-baseline", "hanging")
|
|
179
|
-
.text(this.columns()[0])
|
|
180
|
-
;
|
|
181
|
-
this._q1text
|
|
182
|
-
.attr("height", candleWidth)
|
|
183
|
-
.attr("width", q3x - q1x)
|
|
184
|
-
.attr("display", this.showLabels() ? null : "none")
|
|
185
|
-
.attr("fill", this.textColor())
|
|
186
|
-
.attr("x", 0)
|
|
187
|
-
.attr("y", 0)
|
|
188
|
-
.attr("transform", `translate(${q1x}, ${dataTop - padding})rotate(${upperTextRotation})scale(${textScale})`)
|
|
189
|
-
.attr("font-size", labelFontSize)
|
|
190
|
-
.attr("text-anchor", labelAnchor)
|
|
191
|
-
.attr("alignment-baseline", "middle")
|
|
192
|
-
.text(this.columns()[1])
|
|
193
|
-
;
|
|
194
|
-
this._q2text
|
|
195
|
-
.attr("height", candleWidth)
|
|
196
|
-
.attr("width", q3x - q1x)
|
|
197
|
-
.attr("display", this.showLabels() ? null : "none")
|
|
198
|
-
.attr("fill", this.textColor())
|
|
199
|
-
.attr("x", 0)
|
|
200
|
-
.attr("y", 0)
|
|
201
|
-
.attr("transform", `translate(${q2x}, ${dataTop - padding})rotate(${upperTextRotation})scale(${textScale})`)
|
|
202
|
-
.attr("font-size", labelFontSize)
|
|
203
|
-
.attr("text-anchor", labelAnchor)
|
|
204
|
-
.attr("alignment-baseline", "middle")
|
|
205
|
-
.text(this.columns()[2])
|
|
206
|
-
;
|
|
207
|
-
this._q3text
|
|
208
|
-
.attr("height", candleWidth)
|
|
209
|
-
.attr("width", q3x - q1x)
|
|
210
|
-
.attr("display", this.showLabels() ? null : "none")
|
|
211
|
-
.attr("fill", this.textColor())
|
|
212
|
-
.attr("x", 0)
|
|
213
|
-
.attr("y", 0)
|
|
214
|
-
.attr("transform", `translate(${q3x}, ${dataTop - padding})rotate(${upperTextRotation})scale(${textScale})`)
|
|
215
|
-
.attr("font-size", labelFontSize)
|
|
216
|
-
.attr("text-anchor", labelAnchor)
|
|
217
|
-
.attr("alignment-baseline", "middle")
|
|
218
|
-
.text(this.columns()[3])
|
|
219
|
-
;
|
|
220
|
-
this._q4text
|
|
221
|
-
.attr("height", candleWidth)
|
|
222
|
-
.attr("width", q3x - q1x)
|
|
223
|
-
.attr("display", this.showLabels() ? null : "none")
|
|
224
|
-
.attr("fill", this.textColor())
|
|
225
|
-
.attr("x", 0)
|
|
226
|
-
.attr("y", 0)
|
|
227
|
-
.attr("transform", `translate(${q4x + lineWidth}, ${dataTop - padding})rotate(${upperTextRotation})scale(${textScale})`)
|
|
228
|
-
.attr("font-size", labelFontSize)
|
|
229
|
-
.attr("text-anchor", labelAnchor)
|
|
230
|
-
.attr("alignment-baseline", "baseline")
|
|
231
|
-
.text(this.columns()[4])
|
|
232
|
-
;
|
|
233
|
-
this._q0val
|
|
234
|
-
.attr("height", candleWidth)
|
|
235
|
-
.attr("width", q3x - q1x)
|
|
236
|
-
.attr("display", this.showValues() ? null : "none")
|
|
237
|
-
.attr("fill", this.textColor())
|
|
238
|
-
.attr("x", 0)
|
|
239
|
-
.attr("y", 0)
|
|
240
|
-
.attr("transform", `translate(${q0x}, ${dataBottom + padding})rotate(${lowerTextRotation})scale(${textScale})`)
|
|
241
|
-
.attr("font-size", valueFontSize)
|
|
242
|
-
.attr("text-anchor", valueAnchor)
|
|
243
|
-
.attr("alignment-baseline", "hanging")
|
|
244
|
-
.text(this.data()[0])
|
|
245
|
-
;
|
|
246
|
-
this._q1val
|
|
247
|
-
.attr("height", candleWidth)
|
|
248
|
-
.attr("width", q3x - q1x)
|
|
249
|
-
.attr("display", this.showValues() ? null : "none")
|
|
250
|
-
.attr("fill", this.textColor())
|
|
251
|
-
.attr("x", 0)
|
|
252
|
-
.attr("y", 0)
|
|
253
|
-
.attr("transform", `translate(${q1x}, ${dataBottom + padding})rotate(${lowerTextRotation})scale(${textScale})`)
|
|
254
|
-
.attr("font-size", valueFontSize)
|
|
255
|
-
.attr("text-anchor", valueAnchor)
|
|
256
|
-
.attr("alignment-baseline", "middle")
|
|
257
|
-
.text(this.data()[1])
|
|
258
|
-
;
|
|
259
|
-
this._q2val
|
|
260
|
-
.attr("height", candleWidth)
|
|
261
|
-
.attr("width", q3x - q1x)
|
|
262
|
-
.attr("display", this.showValues() ? null : "none")
|
|
263
|
-
.attr("fill", this.textColor())
|
|
264
|
-
.attr("x", 0)
|
|
265
|
-
.attr("y", 0)
|
|
266
|
-
.attr("transform", `translate(${q2x}, ${dataBottom + padding})rotate(${lowerTextRotation})scale(${textScale})`)
|
|
267
|
-
.attr("font-size", valueFontSize)
|
|
268
|
-
.attr("text-anchor", valueAnchor)
|
|
269
|
-
.attr("alignment-baseline", "middle")
|
|
270
|
-
.text(this.data()[2])
|
|
271
|
-
;
|
|
272
|
-
this._q3val
|
|
273
|
-
.attr("height", candleWidth)
|
|
274
|
-
.attr("width", q3x - q1x)
|
|
275
|
-
.attr("display", this.showValues() ? null : "none")
|
|
276
|
-
.attr("fill", this.textColor())
|
|
277
|
-
.attr("x", 0)
|
|
278
|
-
.attr("y", 0)
|
|
279
|
-
.attr("transform", `translate(${q3x}, ${dataBottom + padding})rotate(${lowerTextRotation})scale(${textScale})`)
|
|
280
|
-
.attr("font-size", valueFontSize)
|
|
281
|
-
.attr("text-anchor", valueAnchor)
|
|
282
|
-
.attr("alignment-baseline", "middle")
|
|
283
|
-
.text(this.data()[3])
|
|
284
|
-
;
|
|
285
|
-
this._q4val
|
|
286
|
-
.attr("height", candleWidth)
|
|
287
|
-
.attr("width", q3x - q1x)
|
|
288
|
-
.attr("display", this.showValues() ? null : "none")
|
|
289
|
-
.attr("fill", this.textColor())
|
|
290
|
-
.attr("x", 0)
|
|
291
|
-
.attr("y", 0)
|
|
292
|
-
.attr("transform", `translate(${q4x + lineWidth}, ${dataBottom + padding})rotate(${lowerTextRotation})scale(${textScale})`)
|
|
293
|
-
.attr("font-size", valueFontSize)
|
|
294
|
-
.attr("text-anchor", valueAnchor)
|
|
295
|
-
.attr("alignment-baseline", "baseline")
|
|
296
|
-
.text(this.data()[4])
|
|
297
|
-
;
|
|
298
|
-
}
|
|
299
|
-
}
|
|
300
|
-
QuartileCandlestick.prototype._class += " chart_QuartileCandlestick";
|
|
301
|
-
|
|
302
|
-
export interface QuartileCandlestick {
|
|
303
|
-
orientation(): "horizontal" | "vertical";
|
|
304
|
-
orientation(_: "horizontal" | "vertical"): this;
|
|
305
|
-
textPadding(): number;
|
|
306
|
-
textPadding(_: number): this;
|
|
307
|
-
edgePadding(): number;
|
|
308
|
-
edgePadding(_: number): this;
|
|
309
|
-
candleWidth(): number;
|
|
310
|
-
candleWidth(_: number): this;
|
|
311
|
-
candleWidth_exists(): boolean;
|
|
312
|
-
lineWidth(): number;
|
|
313
|
-
lineWidth(_: number): this;
|
|
314
|
-
lineColor(): string;
|
|
315
|
-
lineColor(_: string): this;
|
|
316
|
-
innerRectColor(): string;
|
|
317
|
-
innerRectColor(_: string): this;
|
|
318
|
-
lowerTextRotation(): number;
|
|
319
|
-
lowerTextRotation(_: number): this;
|
|
320
|
-
upperTextRotation(): number;
|
|
321
|
-
upperTextRotation(_: number): this;
|
|
322
|
-
roundedCorners(): number;
|
|
323
|
-
roundedCorners(_: number): this;
|
|
324
|
-
labelFontSize(): number;
|
|
325
|
-
labelFontSize(_: number): this;
|
|
326
|
-
valueFontSize(): number;
|
|
327
|
-
valueFontSize(_: number): this;
|
|
328
|
-
textColor(): string;
|
|
329
|
-
textColor(_: string): this;
|
|
330
|
-
showLabels(): boolean;
|
|
331
|
-
showLabels(_: boolean): this;
|
|
332
|
-
showValues(): boolean;
|
|
333
|
-
showValues(_: boolean): this;
|
|
334
|
-
}
|
|
335
|
-
QuartileCandlestick.prototype.publish("textColor", "black", "html-color", "Color of label and value text");
|
|
336
|
-
QuartileCandlestick.prototype.publish("showLabels", true, "boolean", "If true, labels will be shown");
|
|
337
|
-
QuartileCandlestick.prototype.publish("showValues", true, "boolean", "If true, values will be shown");
|
|
338
|
-
QuartileCandlestick.prototype.publish("orientation", "horizontal", "set", "Determines layout", ["horizontal", "vertical"]);
|
|
339
|
-
QuartileCandlestick.prototype.publish("valueFontSize", 12, "number", "Font size of value text (pixels)");
|
|
340
|
-
QuartileCandlestick.prototype.publish("labelFontSize", 12, "number", "Font size of label text (pixels)");
|
|
341
|
-
QuartileCandlestick.prototype.publish("roundedCorners", 8, "number", "Radius of rounded rect corners (pixels)");
|
|
342
|
-
QuartileCandlestick.prototype.publish("lineWidth", 4, "number", "Width of lines (pixels)");
|
|
343
|
-
QuartileCandlestick.prototype.publish("candleWidth", null, "number", "Height of outer rect (pixels)", null, {optional: true});
|
|
344
|
-
QuartileCandlestick.prototype.publish("textPadding", 8, "number", "Padding between outer rect and text (pixels)");
|
|
345
|
-
QuartileCandlestick.prototype.publish("edgePadding", 30, "number", "Padding between outer rect and left/right sides (pixels)");
|
|
346
|
-
QuartileCandlestick.prototype.publish("lineColor", "#333", "html-color", "Color of outer rect and lines");
|
|
347
|
-
QuartileCandlestick.prototype.publish("innerRectColor", "white", "html-color", "Color of the inner rects");
|
|
348
|
-
QuartileCandlestick.prototype.publish("upperTextRotation", -60, "number", "Rotation of label text (degrees)");
|
|
349
|
-
QuartileCandlestick.prototype.publish("lowerTextRotation", -60, "number", "Rotation of value text (degrees)");
|
|
1
|
+
import { SVGWidget } from "@hpcc-js/common";
|
|
2
|
+
import { scaleLinear as d3ScaleLinear } from "d3-scale";
|
|
3
|
+
|
|
4
|
+
export class QuartileCandlestick extends SVGWidget {
|
|
5
|
+
protected _g;
|
|
6
|
+
protected _leftLine;
|
|
7
|
+
protected _rightLine;
|
|
8
|
+
protected _midLine;
|
|
9
|
+
protected _midOuterRect;
|
|
10
|
+
protected _midInnerRect1;
|
|
11
|
+
protected _midInnerRect2;
|
|
12
|
+
protected _q0text;
|
|
13
|
+
protected _q1text;
|
|
14
|
+
protected _q2text;
|
|
15
|
+
protected _q3text;
|
|
16
|
+
protected _q4text;
|
|
17
|
+
protected _q0val;
|
|
18
|
+
protected _q1val;
|
|
19
|
+
protected _q2val;
|
|
20
|
+
protected _q3val;
|
|
21
|
+
protected _q4val;
|
|
22
|
+
constructor() {
|
|
23
|
+
super();
|
|
24
|
+
}
|
|
25
|
+
enter(domNode, element) {
|
|
26
|
+
super.enter(domNode, element);
|
|
27
|
+
this._g = element.append("g");
|
|
28
|
+
this._leftLine = this._g.append("rect");
|
|
29
|
+
this._rightLine = this._g.append("rect");
|
|
30
|
+
this._midLine = this._g.append("rect");
|
|
31
|
+
this._midOuterRect = this._g.append("rect");
|
|
32
|
+
this._midInnerRect1 = this._g.append("rect");
|
|
33
|
+
this._midInnerRect2 = this._g.append("rect");
|
|
34
|
+
this._q0text = this._g.append("text");
|
|
35
|
+
this._q1text = this._g.append("text");
|
|
36
|
+
this._q2text = this._g.append("text");
|
|
37
|
+
this._q3text = this._g.append("text");
|
|
38
|
+
this._q4text = this._g.append("text");
|
|
39
|
+
this._q0val = this._g.append("text");
|
|
40
|
+
this._q1val = this._g.append("text");
|
|
41
|
+
this._q2val = this._g.append("text");
|
|
42
|
+
this._q3val = this._g.append("text");
|
|
43
|
+
this._q4val = this._g.append("text");
|
|
44
|
+
}
|
|
45
|
+
update(domNode, element) {
|
|
46
|
+
super.update(domNode, element);
|
|
47
|
+
const valueSize = (this.orientation() === "horizontal" ? this.width() : this.height()) - this.lineWidth();
|
|
48
|
+
const domainSize = this.orientation() === "horizontal" ? this.height() : this.width();
|
|
49
|
+
const scale = d3ScaleLinear()
|
|
50
|
+
.domain([
|
|
51
|
+
this.data()[0],
|
|
52
|
+
this.data()[4]
|
|
53
|
+
])
|
|
54
|
+
.range([
|
|
55
|
+
this.edgePadding(),
|
|
56
|
+
valueSize - this.edgePadding()
|
|
57
|
+
])
|
|
58
|
+
;
|
|
59
|
+
const candleWidth = this.candleWidth_exists() ? this.candleWidth() : domainSize;
|
|
60
|
+
const lineWidth = this.lineWidth();
|
|
61
|
+
const lineColor = this.lineColor();
|
|
62
|
+
const roundedCorners = this.roundedCorners();
|
|
63
|
+
const q0x = this.edgePadding();
|
|
64
|
+
let q1x = scale(this.data()[1]);
|
|
65
|
+
let q2x = scale(this.data()[2]);
|
|
66
|
+
let q3x = scale(this.data()[3]);
|
|
67
|
+
const dataTop = -candleWidth / 2;
|
|
68
|
+
const dataBottom = candleWidth / 2;
|
|
69
|
+
const upperTextRotation = this.upperTextRotation();
|
|
70
|
+
const lowerTextRotation = this.lowerTextRotation();
|
|
71
|
+
const padding = this.textPadding();
|
|
72
|
+
const labelFontSize = this.labelFontSize();
|
|
73
|
+
const valueFontSize = this.valueFontSize();
|
|
74
|
+
const sz = Math.max(labelFontSize, valueFontSize);
|
|
75
|
+
const q4x = valueSize - q0x;
|
|
76
|
+
if (sz > 0) {
|
|
77
|
+
while (q1x - q0x < sz) {
|
|
78
|
+
q1x += sz;
|
|
79
|
+
}
|
|
80
|
+
while (q2x - q1x < sz) {
|
|
81
|
+
q2x += sz;
|
|
82
|
+
}
|
|
83
|
+
while (q3x - q2x < sz) {
|
|
84
|
+
q3x += sz;
|
|
85
|
+
}
|
|
86
|
+
while (q4x - q3x < sz) {
|
|
87
|
+
q3x -= sz;
|
|
88
|
+
}
|
|
89
|
+
while (q3x - q2x < sz) {
|
|
90
|
+
q2x -= sz;
|
|
91
|
+
}
|
|
92
|
+
while (q2x - q1x < sz) {
|
|
93
|
+
q1x -= sz;
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
let transX = (-valueSize / 2) - (this.lineWidth() / 2);
|
|
97
|
+
let transY = 0;
|
|
98
|
+
let rotate = 0;
|
|
99
|
+
const s = 1;
|
|
100
|
+
let textScale = 1;
|
|
101
|
+
let labelAnchor = "start";
|
|
102
|
+
let valueAnchor = "end";
|
|
103
|
+
if (this.orientation() === "vertical") {
|
|
104
|
+
transX = 0;
|
|
105
|
+
transY = valueSize / 2 + (this.lineWidth() / 2);
|
|
106
|
+
rotate = -90;
|
|
107
|
+
labelAnchor = "end";
|
|
108
|
+
valueAnchor = "start";
|
|
109
|
+
textScale = -1;
|
|
110
|
+
}
|
|
111
|
+
this._g
|
|
112
|
+
.style("shape-rendering", "crispEdges")
|
|
113
|
+
.attr("transform", `translate(${transX},${transY})rotate(${rotate})scale(${s})`)
|
|
114
|
+
;
|
|
115
|
+
this._leftLine
|
|
116
|
+
.attr("fill", lineColor)
|
|
117
|
+
.attr("height", candleWidth)
|
|
118
|
+
.attr("width", lineWidth)
|
|
119
|
+
.attr("x", q0x)
|
|
120
|
+
.attr("y", dataTop)
|
|
121
|
+
.attr("rx", roundedCorners)
|
|
122
|
+
.attr("ry", roundedCorners)
|
|
123
|
+
;
|
|
124
|
+
this._rightLine
|
|
125
|
+
.attr("class", "right-line")
|
|
126
|
+
.attr("fill", lineColor)
|
|
127
|
+
.attr("height", candleWidth)
|
|
128
|
+
.attr("width", lineWidth)
|
|
129
|
+
.attr("x", q4x)
|
|
130
|
+
.attr("y", dataTop)
|
|
131
|
+
.attr("rx", roundedCorners)
|
|
132
|
+
.attr("ry", roundedCorners)
|
|
133
|
+
;
|
|
134
|
+
this._midLine
|
|
135
|
+
.attr("fill", lineColor)
|
|
136
|
+
.attr("height", lineWidth)
|
|
137
|
+
.attr("width", q4x - q0x)
|
|
138
|
+
.attr("x", q0x)
|
|
139
|
+
.attr("y", -lineWidth / 2)
|
|
140
|
+
;
|
|
141
|
+
this._midOuterRect
|
|
142
|
+
.attr("fill", lineColor)
|
|
143
|
+
.attr("height", candleWidth)
|
|
144
|
+
.attr("width", q3x - q1x)
|
|
145
|
+
.attr("x", q1x)
|
|
146
|
+
.attr("y", dataTop)
|
|
147
|
+
.attr("rx", roundedCorners)
|
|
148
|
+
.attr("ry", roundedCorners)
|
|
149
|
+
;
|
|
150
|
+
this._midInnerRect1
|
|
151
|
+
.attr("fill", this.innerRectColor())
|
|
152
|
+
.attr("height", candleWidth - (lineWidth * 2))
|
|
153
|
+
.attr("width", q2x - (q1x + (lineWidth * 2)))
|
|
154
|
+
.attr("x", q1x + lineWidth)
|
|
155
|
+
.attr("y", lineWidth - (candleWidth / 2))
|
|
156
|
+
.attr("rx", roundedCorners * 0.618)
|
|
157
|
+
.attr("ry", roundedCorners * 0.618)
|
|
158
|
+
;
|
|
159
|
+
this._midInnerRect2
|
|
160
|
+
.attr("fill", this.innerRectColor())
|
|
161
|
+
.attr("height", candleWidth - (lineWidth * 2))
|
|
162
|
+
.attr("width", q3x - q2x - lineWidth)
|
|
163
|
+
.attr("x", q2x)
|
|
164
|
+
.attr("y", lineWidth - (candleWidth / 2))
|
|
165
|
+
.attr("rx", roundedCorners * 0.618)
|
|
166
|
+
.attr("ry", roundedCorners * 0.618)
|
|
167
|
+
;
|
|
168
|
+
this._q0text
|
|
169
|
+
.attr("height", candleWidth)
|
|
170
|
+
.attr("width", q3x - q1x)
|
|
171
|
+
.attr("display", this.showLabels() ? null : "none")
|
|
172
|
+
.attr("fill", this.textColor())
|
|
173
|
+
.attr("x", 0)
|
|
174
|
+
.attr("y", 0)
|
|
175
|
+
.attr("transform", `translate(${q0x}, ${dataTop - padding})rotate(${upperTextRotation})scale(${textScale})`)
|
|
176
|
+
.attr("font-size", labelFontSize)
|
|
177
|
+
.attr("text-anchor", labelAnchor)
|
|
178
|
+
.attr("alignment-baseline", "hanging")
|
|
179
|
+
.text(this.columns()[0])
|
|
180
|
+
;
|
|
181
|
+
this._q1text
|
|
182
|
+
.attr("height", candleWidth)
|
|
183
|
+
.attr("width", q3x - q1x)
|
|
184
|
+
.attr("display", this.showLabels() ? null : "none")
|
|
185
|
+
.attr("fill", this.textColor())
|
|
186
|
+
.attr("x", 0)
|
|
187
|
+
.attr("y", 0)
|
|
188
|
+
.attr("transform", `translate(${q1x}, ${dataTop - padding})rotate(${upperTextRotation})scale(${textScale})`)
|
|
189
|
+
.attr("font-size", labelFontSize)
|
|
190
|
+
.attr("text-anchor", labelAnchor)
|
|
191
|
+
.attr("alignment-baseline", "middle")
|
|
192
|
+
.text(this.columns()[1])
|
|
193
|
+
;
|
|
194
|
+
this._q2text
|
|
195
|
+
.attr("height", candleWidth)
|
|
196
|
+
.attr("width", q3x - q1x)
|
|
197
|
+
.attr("display", this.showLabels() ? null : "none")
|
|
198
|
+
.attr("fill", this.textColor())
|
|
199
|
+
.attr("x", 0)
|
|
200
|
+
.attr("y", 0)
|
|
201
|
+
.attr("transform", `translate(${q2x}, ${dataTop - padding})rotate(${upperTextRotation})scale(${textScale})`)
|
|
202
|
+
.attr("font-size", labelFontSize)
|
|
203
|
+
.attr("text-anchor", labelAnchor)
|
|
204
|
+
.attr("alignment-baseline", "middle")
|
|
205
|
+
.text(this.columns()[2])
|
|
206
|
+
;
|
|
207
|
+
this._q3text
|
|
208
|
+
.attr("height", candleWidth)
|
|
209
|
+
.attr("width", q3x - q1x)
|
|
210
|
+
.attr("display", this.showLabels() ? null : "none")
|
|
211
|
+
.attr("fill", this.textColor())
|
|
212
|
+
.attr("x", 0)
|
|
213
|
+
.attr("y", 0)
|
|
214
|
+
.attr("transform", `translate(${q3x}, ${dataTop - padding})rotate(${upperTextRotation})scale(${textScale})`)
|
|
215
|
+
.attr("font-size", labelFontSize)
|
|
216
|
+
.attr("text-anchor", labelAnchor)
|
|
217
|
+
.attr("alignment-baseline", "middle")
|
|
218
|
+
.text(this.columns()[3])
|
|
219
|
+
;
|
|
220
|
+
this._q4text
|
|
221
|
+
.attr("height", candleWidth)
|
|
222
|
+
.attr("width", q3x - q1x)
|
|
223
|
+
.attr("display", this.showLabels() ? null : "none")
|
|
224
|
+
.attr("fill", this.textColor())
|
|
225
|
+
.attr("x", 0)
|
|
226
|
+
.attr("y", 0)
|
|
227
|
+
.attr("transform", `translate(${q4x + lineWidth}, ${dataTop - padding})rotate(${upperTextRotation})scale(${textScale})`)
|
|
228
|
+
.attr("font-size", labelFontSize)
|
|
229
|
+
.attr("text-anchor", labelAnchor)
|
|
230
|
+
.attr("alignment-baseline", "baseline")
|
|
231
|
+
.text(this.columns()[4])
|
|
232
|
+
;
|
|
233
|
+
this._q0val
|
|
234
|
+
.attr("height", candleWidth)
|
|
235
|
+
.attr("width", q3x - q1x)
|
|
236
|
+
.attr("display", this.showValues() ? null : "none")
|
|
237
|
+
.attr("fill", this.textColor())
|
|
238
|
+
.attr("x", 0)
|
|
239
|
+
.attr("y", 0)
|
|
240
|
+
.attr("transform", `translate(${q0x}, ${dataBottom + padding})rotate(${lowerTextRotation})scale(${textScale})`)
|
|
241
|
+
.attr("font-size", valueFontSize)
|
|
242
|
+
.attr("text-anchor", valueAnchor)
|
|
243
|
+
.attr("alignment-baseline", "hanging")
|
|
244
|
+
.text(this.data()[0])
|
|
245
|
+
;
|
|
246
|
+
this._q1val
|
|
247
|
+
.attr("height", candleWidth)
|
|
248
|
+
.attr("width", q3x - q1x)
|
|
249
|
+
.attr("display", this.showValues() ? null : "none")
|
|
250
|
+
.attr("fill", this.textColor())
|
|
251
|
+
.attr("x", 0)
|
|
252
|
+
.attr("y", 0)
|
|
253
|
+
.attr("transform", `translate(${q1x}, ${dataBottom + padding})rotate(${lowerTextRotation})scale(${textScale})`)
|
|
254
|
+
.attr("font-size", valueFontSize)
|
|
255
|
+
.attr("text-anchor", valueAnchor)
|
|
256
|
+
.attr("alignment-baseline", "middle")
|
|
257
|
+
.text(this.data()[1])
|
|
258
|
+
;
|
|
259
|
+
this._q2val
|
|
260
|
+
.attr("height", candleWidth)
|
|
261
|
+
.attr("width", q3x - q1x)
|
|
262
|
+
.attr("display", this.showValues() ? null : "none")
|
|
263
|
+
.attr("fill", this.textColor())
|
|
264
|
+
.attr("x", 0)
|
|
265
|
+
.attr("y", 0)
|
|
266
|
+
.attr("transform", `translate(${q2x}, ${dataBottom + padding})rotate(${lowerTextRotation})scale(${textScale})`)
|
|
267
|
+
.attr("font-size", valueFontSize)
|
|
268
|
+
.attr("text-anchor", valueAnchor)
|
|
269
|
+
.attr("alignment-baseline", "middle")
|
|
270
|
+
.text(this.data()[2])
|
|
271
|
+
;
|
|
272
|
+
this._q3val
|
|
273
|
+
.attr("height", candleWidth)
|
|
274
|
+
.attr("width", q3x - q1x)
|
|
275
|
+
.attr("display", this.showValues() ? null : "none")
|
|
276
|
+
.attr("fill", this.textColor())
|
|
277
|
+
.attr("x", 0)
|
|
278
|
+
.attr("y", 0)
|
|
279
|
+
.attr("transform", `translate(${q3x}, ${dataBottom + padding})rotate(${lowerTextRotation})scale(${textScale})`)
|
|
280
|
+
.attr("font-size", valueFontSize)
|
|
281
|
+
.attr("text-anchor", valueAnchor)
|
|
282
|
+
.attr("alignment-baseline", "middle")
|
|
283
|
+
.text(this.data()[3])
|
|
284
|
+
;
|
|
285
|
+
this._q4val
|
|
286
|
+
.attr("height", candleWidth)
|
|
287
|
+
.attr("width", q3x - q1x)
|
|
288
|
+
.attr("display", this.showValues() ? null : "none")
|
|
289
|
+
.attr("fill", this.textColor())
|
|
290
|
+
.attr("x", 0)
|
|
291
|
+
.attr("y", 0)
|
|
292
|
+
.attr("transform", `translate(${q4x + lineWidth}, ${dataBottom + padding})rotate(${lowerTextRotation})scale(${textScale})`)
|
|
293
|
+
.attr("font-size", valueFontSize)
|
|
294
|
+
.attr("text-anchor", valueAnchor)
|
|
295
|
+
.attr("alignment-baseline", "baseline")
|
|
296
|
+
.text(this.data()[4])
|
|
297
|
+
;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
QuartileCandlestick.prototype._class += " chart_QuartileCandlestick";
|
|
301
|
+
|
|
302
|
+
export interface QuartileCandlestick {
|
|
303
|
+
orientation(): "horizontal" | "vertical";
|
|
304
|
+
orientation(_: "horizontal" | "vertical"): this;
|
|
305
|
+
textPadding(): number;
|
|
306
|
+
textPadding(_: number): this;
|
|
307
|
+
edgePadding(): number;
|
|
308
|
+
edgePadding(_: number): this;
|
|
309
|
+
candleWidth(): number;
|
|
310
|
+
candleWidth(_: number): this;
|
|
311
|
+
candleWidth_exists(): boolean;
|
|
312
|
+
lineWidth(): number;
|
|
313
|
+
lineWidth(_: number): this;
|
|
314
|
+
lineColor(): string;
|
|
315
|
+
lineColor(_: string): this;
|
|
316
|
+
innerRectColor(): string;
|
|
317
|
+
innerRectColor(_: string): this;
|
|
318
|
+
lowerTextRotation(): number;
|
|
319
|
+
lowerTextRotation(_: number): this;
|
|
320
|
+
upperTextRotation(): number;
|
|
321
|
+
upperTextRotation(_: number): this;
|
|
322
|
+
roundedCorners(): number;
|
|
323
|
+
roundedCorners(_: number): this;
|
|
324
|
+
labelFontSize(): number;
|
|
325
|
+
labelFontSize(_: number): this;
|
|
326
|
+
valueFontSize(): number;
|
|
327
|
+
valueFontSize(_: number): this;
|
|
328
|
+
textColor(): string;
|
|
329
|
+
textColor(_: string): this;
|
|
330
|
+
showLabels(): boolean;
|
|
331
|
+
showLabels(_: boolean): this;
|
|
332
|
+
showValues(): boolean;
|
|
333
|
+
showValues(_: boolean): this;
|
|
334
|
+
}
|
|
335
|
+
QuartileCandlestick.prototype.publish("textColor", "black", "html-color", "Color of label and value text");
|
|
336
|
+
QuartileCandlestick.prototype.publish("showLabels", true, "boolean", "If true, labels will be shown");
|
|
337
|
+
QuartileCandlestick.prototype.publish("showValues", true, "boolean", "If true, values will be shown");
|
|
338
|
+
QuartileCandlestick.prototype.publish("orientation", "horizontal", "set", "Determines layout", ["horizontal", "vertical"]);
|
|
339
|
+
QuartileCandlestick.prototype.publish("valueFontSize", 12, "number", "Font size of value text (pixels)");
|
|
340
|
+
QuartileCandlestick.prototype.publish("labelFontSize", 12, "number", "Font size of label text (pixels)");
|
|
341
|
+
QuartileCandlestick.prototype.publish("roundedCorners", 8, "number", "Radius of rounded rect corners (pixels)");
|
|
342
|
+
QuartileCandlestick.prototype.publish("lineWidth", 4, "number", "Width of lines (pixels)");
|
|
343
|
+
QuartileCandlestick.prototype.publish("candleWidth", null, "number", "Height of outer rect (pixels)", null, {optional: true});
|
|
344
|
+
QuartileCandlestick.prototype.publish("textPadding", 8, "number", "Padding between outer rect and text (pixels)");
|
|
345
|
+
QuartileCandlestick.prototype.publish("edgePadding", 30, "number", "Padding between outer rect and left/right sides (pixels)");
|
|
346
|
+
QuartileCandlestick.prototype.publish("lineColor", "#333", "html-color", "Color of outer rect and lines");
|
|
347
|
+
QuartileCandlestick.prototype.publish("innerRectColor", "white", "html-color", "Color of the inner rects");
|
|
348
|
+
QuartileCandlestick.prototype.publish("upperTextRotation", -60, "number", "Rotation of label text (degrees)");
|
|
349
|
+
QuartileCandlestick.prototype.publish("lowerTextRotation", -60, "number", "Rotation of value text (degrees)");
|