@hpcc-js/chart 3.7.2 → 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
package/src/StatChart.ts
CHANGED
|
@@ -1,261 +1,261 @@
|
|
|
1
|
-
import { format as d3Format, HTMLWidget, Palette } from "@hpcc-js/common";
|
|
2
|
-
import { QuartileCandlestick } from "./QuartileCandlestick.ts";
|
|
3
|
-
import { Scatter } from "./Scatter.ts";
|
|
4
|
-
|
|
5
|
-
const rainbow = Palette.rainbow("Blues");
|
|
6
|
-
const palette = Palette.ordinal("Quartile", [rainbow(100, 0, 100), rainbow(50, 0, 100), rainbow(50, 0, 100), rainbow(75, 0, 100)]);
|
|
7
|
-
palette("Std. Dev.");
|
|
8
|
-
palette("MinMax");
|
|
9
|
-
palette("25%");
|
|
10
|
-
palette("50%");
|
|
11
|
-
|
|
12
|
-
type View = "min_max" | "25_75" | "normal";
|
|
13
|
-
type Tick = { label: string, value: number };
|
|
14
|
-
type Ticks = Tick[];
|
|
15
|
-
type AxisTick = { label: string, value: string };
|
|
16
|
-
type AxisTicks = AxisTick[];
|
|
17
|
-
|
|
18
|
-
function myFormatter(format: string): (num: number) => string {
|
|
19
|
-
const formatter = d3Format(format);
|
|
20
|
-
return function (num: number) {
|
|
21
|
-
const strVal = (Math.round(num * 100) / 100).toString();
|
|
22
|
-
if (strVal.length <= 4) return strVal;
|
|
23
|
-
return formatter(num);
|
|
24
|
-
};
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export type StatChartView = "min_max" | "25_75" | "normal";
|
|
28
|
-
export type Quartiles = [number, number, number, number, number];
|
|
29
|
-
export type Data = [[number, number, number, number, number, number, number]];
|
|
30
|
-
|
|
31
|
-
export class StatChart extends HTMLWidget {
|
|
32
|
-
|
|
33
|
-
protected _selectElement: any;
|
|
34
|
-
protected _tickFormatter: (_: number) => string;
|
|
35
|
-
|
|
36
|
-
protected _bellCurve: Scatter = new Scatter()
|
|
37
|
-
.columns(["", "Std. Dev."])
|
|
38
|
-
.paletteID("Quartile")
|
|
39
|
-
.interpolate_default("basis")
|
|
40
|
-
.pointSize(0)
|
|
41
|
-
.xAxisType("linear")
|
|
42
|
-
.xAxisOverlapMode("none")
|
|
43
|
-
.xAxisTickFormat(",")
|
|
44
|
-
.yAxisHidden(true)
|
|
45
|
-
.yAxisDomainLow(0)
|
|
46
|
-
.yAxisDomainHigh(110)
|
|
47
|
-
.yAxisGuideLines(false) as Scatter
|
|
48
|
-
;
|
|
49
|
-
|
|
50
|
-
protected _candle = new QuartileCandlestick()
|
|
51
|
-
.columns(["Min", "25%", "50%", "75%", "Max"])
|
|
52
|
-
.edgePadding(0)
|
|
53
|
-
.roundedCorners(1)
|
|
54
|
-
.lineWidth(1)
|
|
55
|
-
.upperTextRotation(-90)
|
|
56
|
-
.lowerTextRotation(-90)
|
|
57
|
-
.labelFontSize(0)
|
|
58
|
-
.valueFontSize(0)
|
|
59
|
-
.lineColor(rainbow(90, 0, 100))
|
|
60
|
-
.innerRectColor(rainbow(10, 0, 100))
|
|
61
|
-
;
|
|
62
|
-
|
|
63
|
-
constructor() {
|
|
64
|
-
super();
|
|
65
|
-
this
|
|
66
|
-
.columns(["Min", "25%", "50%", "75%", "Max", "Mean", "Std. Dev."])
|
|
67
|
-
;
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
protected stdDev(degrees: number): number {
|
|
71
|
-
return this.mean() + degrees * this.standardDeviation();
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
protected formatStdDev(degrees: number): string {
|
|
75
|
-
return this._tickFormatter(this.stdDev(degrees));
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
protected quartile(q: 0 | 1 | 2 | 3 | 4): number {
|
|
79
|
-
return this.quartiles()[q];
|
|
80
|
-
}
|
|
81
|
-
|
|
82
|
-
protected formatQ(q: 0 | 1 | 2 | 3 | 4): string {
|
|
83
|
-
return this._tickFormatter(this.quartile(q));
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
protected domain(mode: View): [number, number] {
|
|
87
|
-
switch (mode) {
|
|
88
|
-
case "25_75":
|
|
89
|
-
return [this.quartile(1), this.quartile(3)];
|
|
90
|
-
case "normal":
|
|
91
|
-
return [this.stdDev(-4), this.stdDev(4)];
|
|
92
|
-
case "min_max":
|
|
93
|
-
default:
|
|
94
|
-
return [this.quartile(0), this.quartile(4)];
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
protected min(): number {
|
|
99
|
-
return this.quartile(0);
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
protected max(): number {
|
|
103
|
-
return this.quartile(4);
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
data(): Data;
|
|
107
|
-
data(_: Data): this;
|
|
108
|
-
data(_?: Data): Data | this {
|
|
109
|
-
if (!arguments.length) return [[...this.quartiles(), this.mean(), this.standardDeviation()]];
|
|
110
|
-
const row = _[0];
|
|
111
|
-
this.quartiles([row[0], row[1], row[2], row[3], row[4]]);
|
|
112
|
-
this.mean(row[5]);
|
|
113
|
-
this.standardDeviation(row[6]);
|
|
114
|
-
return this;
|
|
115
|
-
}
|
|
116
|
-
|
|
117
|
-
enter(domNode, element) {
|
|
118
|
-
super.enter(domNode, element);
|
|
119
|
-
|
|
120
|
-
this._bellCurve.target(element.append("div").node());
|
|
121
|
-
|
|
122
|
-
this._candle.target(element.append("div").node());
|
|
123
|
-
|
|
124
|
-
this._selectElement = element.append("div")
|
|
125
|
-
.style("position", "absolute")
|
|
126
|
-
.style("top", "0px")
|
|
127
|
-
.style("right", "0px").append("select")
|
|
128
|
-
.on("change", () => {
|
|
129
|
-
this.view(this._selectElement.node().value);
|
|
130
|
-
this.lazyRender();
|
|
131
|
-
})
|
|
132
|
-
;
|
|
133
|
-
this._selectElement.append("option").attr("value", "min_max").text("Min / Max");
|
|
134
|
-
this._selectElement.append("option").attr("value", "25_75").text("25% / 75%");
|
|
135
|
-
this._selectElement.append("option").attr("value", "normal").text("Normal");
|
|
136
|
-
}
|
|
137
|
-
|
|
138
|
-
protected bellTicks(mode: View): AxisTicks {
|
|
139
|
-
let ticks: Ticks;
|
|
140
|
-
switch (mode) {
|
|
141
|
-
case "25_75":
|
|
142
|
-
ticks = [
|
|
143
|
-
{ label: this.formatQ(1), value: this.quartile(1) },
|
|
144
|
-
{ label: this.formatQ(2), value: this.quartile(2) },
|
|
145
|
-
{ label: this.formatQ(3), value: this.quartile(3) }
|
|
146
|
-
];
|
|
147
|
-
break;
|
|
148
|
-
case "normal":
|
|
149
|
-
ticks = [
|
|
150
|
-
{ label: this.formatStdDev(-4), value: this.stdDev(-4) },
|
|
151
|
-
{ label: "-3σ", value: this.stdDev(-3) },
|
|
152
|
-
{ label: "-2σ", value: this.stdDev(-2) },
|
|
153
|
-
{ label: "-1σ", value: this.stdDev(-1) },
|
|
154
|
-
{ label: this.formatStdDev(0), value: this.stdDev(0) },
|
|
155
|
-
{ label: "+1σ", value: this.stdDev(1) },
|
|
156
|
-
{ label: "+2σ", value: this.stdDev(2) },
|
|
157
|
-
{ label: "+3σ", value: this.stdDev(3) },
|
|
158
|
-
{ label: this.formatStdDev(4), value: this.stdDev(4) }
|
|
159
|
-
];
|
|
160
|
-
break;
|
|
161
|
-
case "min_max":
|
|
162
|
-
default:
|
|
163
|
-
ticks = [
|
|
164
|
-
{ label: this.formatQ(0), value: this.quartile(0) },
|
|
165
|
-
{ label: this.formatQ(1), value: this.quartile(1) },
|
|
166
|
-
{ label: this.formatQ(2), value: this.quartile(2) },
|
|
167
|
-
{ label: this.formatQ(3), value: this.quartile(3) },
|
|
168
|
-
{ label: this.formatQ(4), value: this.quartile(4) }
|
|
169
|
-
];
|
|
170
|
-
}
|
|
171
|
-
|
|
172
|
-
const [domainLow, domainHigh] = this.domain(this._selectElement.node().value);
|
|
173
|
-
return ticks
|
|
174
|
-
.filter(sd => sd.value >= domainLow && sd.value <= domainHigh)
|
|
175
|
-
.map(sd => ({ label: sd.label, value: sd.value.toString() }))
|
|
176
|
-
;
|
|
177
|
-
}
|
|
178
|
-
|
|
179
|
-
updateScatter() {
|
|
180
|
-
const mode = this._selectElement.node().value;
|
|
181
|
-
const [domainLow, domainHigh] = this.domain(mode);
|
|
182
|
-
const padding = (domainHigh - domainLow) * (this.domainPadding() / 100);
|
|
183
|
-
|
|
184
|
-
this._bellCurve
|
|
185
|
-
.xAxisDomainLow(domainLow - padding)
|
|
186
|
-
.xAxisDomainHigh(domainHigh + padding)
|
|
187
|
-
.xAxisTicks(this.bellTicks(mode))
|
|
188
|
-
.data([
|
|
189
|
-
[this.stdDev(-4), 0],
|
|
190
|
-
[this.stdDev(-3), 0.3],
|
|
191
|
-
[this.stdDev(-2), 5],
|
|
192
|
-
[this.stdDev(-1), 68],
|
|
193
|
-
[this.stdDev(0), 100],
|
|
194
|
-
[this.stdDev(1), 68],
|
|
195
|
-
[this.stdDev(2), 5],
|
|
196
|
-
[this.stdDev(3), 0.3],
|
|
197
|
-
[this.stdDev(4), 0]
|
|
198
|
-
])
|
|
199
|
-
.resize({ width: this.width(), height: this.height() - this.candleHeight() })
|
|
200
|
-
.render()
|
|
201
|
-
;
|
|
202
|
-
}
|
|
203
|
-
|
|
204
|
-
updateCandle() {
|
|
205
|
-
const candleX = this._bellCurve.dataPos(this.quartile(0));
|
|
206
|
-
const candleW = this._bellCurve.dataPos(this.quartile(4)) - candleX;
|
|
207
|
-
this._candle
|
|
208
|
-
.resize({ width: this.width(), height: this.candleHeight() })
|
|
209
|
-
.pos({ x: (candleX + candleW / 2) + 2, y: this.candleHeight() / 2 })
|
|
210
|
-
.width(candleW)
|
|
211
|
-
.candleWidth(this.candleHeight())
|
|
212
|
-
.data(this.quartiles())
|
|
213
|
-
.render()
|
|
214
|
-
;
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
update(domNode, element) {
|
|
218
|
-
super.update(domNode, element);
|
|
219
|
-
this._tickFormatter = myFormatter(this.tickFormat());
|
|
220
|
-
this._selectElement.node().value = this.view();
|
|
221
|
-
this.updateScatter();
|
|
222
|
-
this.updateCandle();
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
exit(domNode, element) {
|
|
226
|
-
this._bellCurve.target(null);
|
|
227
|
-
this._candle.target(null);
|
|
228
|
-
this._selectElement.remove();
|
|
229
|
-
|
|
230
|
-
super.exit(domNode, element);
|
|
231
|
-
}
|
|
232
|
-
}
|
|
233
|
-
StatChart.prototype._class += " chart_StatChart";
|
|
234
|
-
|
|
235
|
-
export interface StatChart {
|
|
236
|
-
view(): StatChartView;
|
|
237
|
-
view(_: StatChartView): this;
|
|
238
|
-
|
|
239
|
-
tickFormat(): string;
|
|
240
|
-
tickFormat(_: string): this;
|
|
241
|
-
candleHeight(): number;
|
|
242
|
-
candleHeight(_: number): this;
|
|
243
|
-
domainPadding(): number;
|
|
244
|
-
domainPadding(_: number): this;
|
|
245
|
-
|
|
246
|
-
mean(): number;
|
|
247
|
-
mean(_: number): this;
|
|
248
|
-
standardDeviation(): number;
|
|
249
|
-
standardDeviation(_: number): this;
|
|
250
|
-
quartiles(): Quartiles;
|
|
251
|
-
quartiles(_: Quartiles): this;
|
|
252
|
-
}
|
|
253
|
-
StatChart.prototype.publish("view", "min_max", "set", "View", ["min_max", "25_75", "normal"]);
|
|
254
|
-
|
|
255
|
-
StatChart.prototype.publish("tickFormat", ".2e", "string", "X-Axis Tick Format");
|
|
256
|
-
StatChart.prototype.publish("candleHeight", 20, "number", "Height of candle widget (pixels)");
|
|
257
|
-
StatChart.prototype.publish("domainPadding", 10, "number", "Domain value padding");
|
|
258
|
-
|
|
259
|
-
StatChart.prototype.publish("mean", .5, "number", "Mean");
|
|
260
|
-
StatChart.prototype.publish("standardDeviation", .125, "number", "Standard Deviation (σ)");
|
|
261
|
-
StatChart.prototype.publish("quartiles", [0, .25, .5, .75, 1], "object", "Quartiles (Min, 25%, 50%, 75%, Max)");
|
|
1
|
+
import { format as d3Format, HTMLWidget, Palette } from "@hpcc-js/common";
|
|
2
|
+
import { QuartileCandlestick } from "./QuartileCandlestick.ts";
|
|
3
|
+
import { Scatter } from "./Scatter.ts";
|
|
4
|
+
|
|
5
|
+
const rainbow = Palette.rainbow("Blues");
|
|
6
|
+
const palette = Palette.ordinal("Quartile", [rainbow(100, 0, 100), rainbow(50, 0, 100), rainbow(50, 0, 100), rainbow(75, 0, 100)]);
|
|
7
|
+
palette("Std. Dev.");
|
|
8
|
+
palette("MinMax");
|
|
9
|
+
palette("25%");
|
|
10
|
+
palette("50%");
|
|
11
|
+
|
|
12
|
+
type View = "min_max" | "25_75" | "normal";
|
|
13
|
+
type Tick = { label: string, value: number };
|
|
14
|
+
type Ticks = Tick[];
|
|
15
|
+
type AxisTick = { label: string, value: string };
|
|
16
|
+
type AxisTicks = AxisTick[];
|
|
17
|
+
|
|
18
|
+
function myFormatter(format: string): (num: number) => string {
|
|
19
|
+
const formatter = d3Format(format);
|
|
20
|
+
return function (num: number) {
|
|
21
|
+
const strVal = (Math.round(num * 100) / 100).toString();
|
|
22
|
+
if (strVal.length <= 4) return strVal;
|
|
23
|
+
return formatter(num);
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export type StatChartView = "min_max" | "25_75" | "normal";
|
|
28
|
+
export type Quartiles = [number, number, number, number, number];
|
|
29
|
+
export type Data = [[number, number, number, number, number, number, number]];
|
|
30
|
+
|
|
31
|
+
export class StatChart extends HTMLWidget {
|
|
32
|
+
|
|
33
|
+
protected _selectElement: any;
|
|
34
|
+
protected _tickFormatter: (_: number) => string;
|
|
35
|
+
|
|
36
|
+
protected _bellCurve: Scatter = new Scatter()
|
|
37
|
+
.columns(["", "Std. Dev."])
|
|
38
|
+
.paletteID("Quartile")
|
|
39
|
+
.interpolate_default("basis")
|
|
40
|
+
.pointSize(0)
|
|
41
|
+
.xAxisType("linear")
|
|
42
|
+
.xAxisOverlapMode("none")
|
|
43
|
+
.xAxisTickFormat(",")
|
|
44
|
+
.yAxisHidden(true)
|
|
45
|
+
.yAxisDomainLow(0)
|
|
46
|
+
.yAxisDomainHigh(110)
|
|
47
|
+
.yAxisGuideLines(false) as Scatter
|
|
48
|
+
;
|
|
49
|
+
|
|
50
|
+
protected _candle = new QuartileCandlestick()
|
|
51
|
+
.columns(["Min", "25%", "50%", "75%", "Max"])
|
|
52
|
+
.edgePadding(0)
|
|
53
|
+
.roundedCorners(1)
|
|
54
|
+
.lineWidth(1)
|
|
55
|
+
.upperTextRotation(-90)
|
|
56
|
+
.lowerTextRotation(-90)
|
|
57
|
+
.labelFontSize(0)
|
|
58
|
+
.valueFontSize(0)
|
|
59
|
+
.lineColor(rainbow(90, 0, 100))
|
|
60
|
+
.innerRectColor(rainbow(10, 0, 100))
|
|
61
|
+
;
|
|
62
|
+
|
|
63
|
+
constructor() {
|
|
64
|
+
super();
|
|
65
|
+
this
|
|
66
|
+
.columns(["Min", "25%", "50%", "75%", "Max", "Mean", "Std. Dev."])
|
|
67
|
+
;
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
protected stdDev(degrees: number): number {
|
|
71
|
+
return this.mean() + degrees * this.standardDeviation();
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
protected formatStdDev(degrees: number): string {
|
|
75
|
+
return this._tickFormatter(this.stdDev(degrees));
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
protected quartile(q: 0 | 1 | 2 | 3 | 4): number {
|
|
79
|
+
return this.quartiles()[q];
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
protected formatQ(q: 0 | 1 | 2 | 3 | 4): string {
|
|
83
|
+
return this._tickFormatter(this.quartile(q));
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
protected domain(mode: View): [number, number] {
|
|
87
|
+
switch (mode) {
|
|
88
|
+
case "25_75":
|
|
89
|
+
return [this.quartile(1), this.quartile(3)];
|
|
90
|
+
case "normal":
|
|
91
|
+
return [this.stdDev(-4), this.stdDev(4)];
|
|
92
|
+
case "min_max":
|
|
93
|
+
default:
|
|
94
|
+
return [this.quartile(0), this.quartile(4)];
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
protected min(): number {
|
|
99
|
+
return this.quartile(0);
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
protected max(): number {
|
|
103
|
+
return this.quartile(4);
|
|
104
|
+
}
|
|
105
|
+
|
|
106
|
+
data(): Data;
|
|
107
|
+
data(_: Data): this;
|
|
108
|
+
data(_?: Data): Data | this {
|
|
109
|
+
if (!arguments.length) return [[...this.quartiles(), this.mean(), this.standardDeviation()]];
|
|
110
|
+
const row = _[0];
|
|
111
|
+
this.quartiles([row[0], row[1], row[2], row[3], row[4]]);
|
|
112
|
+
this.mean(row[5]);
|
|
113
|
+
this.standardDeviation(row[6]);
|
|
114
|
+
return this;
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
enter(domNode, element) {
|
|
118
|
+
super.enter(domNode, element);
|
|
119
|
+
|
|
120
|
+
this._bellCurve.target(element.append("div").node());
|
|
121
|
+
|
|
122
|
+
this._candle.target(element.append("div").node());
|
|
123
|
+
|
|
124
|
+
this._selectElement = element.append("div")
|
|
125
|
+
.style("position", "absolute")
|
|
126
|
+
.style("top", "0px")
|
|
127
|
+
.style("right", "0px").append("select")
|
|
128
|
+
.on("change", () => {
|
|
129
|
+
this.view(this._selectElement.node().value);
|
|
130
|
+
this.lazyRender();
|
|
131
|
+
})
|
|
132
|
+
;
|
|
133
|
+
this._selectElement.append("option").attr("value", "min_max").text("Min / Max");
|
|
134
|
+
this._selectElement.append("option").attr("value", "25_75").text("25% / 75%");
|
|
135
|
+
this._selectElement.append("option").attr("value", "normal").text("Normal");
|
|
136
|
+
}
|
|
137
|
+
|
|
138
|
+
protected bellTicks(mode: View): AxisTicks {
|
|
139
|
+
let ticks: Ticks;
|
|
140
|
+
switch (mode) {
|
|
141
|
+
case "25_75":
|
|
142
|
+
ticks = [
|
|
143
|
+
{ label: this.formatQ(1), value: this.quartile(1) },
|
|
144
|
+
{ label: this.formatQ(2), value: this.quartile(2) },
|
|
145
|
+
{ label: this.formatQ(3), value: this.quartile(3) }
|
|
146
|
+
];
|
|
147
|
+
break;
|
|
148
|
+
case "normal":
|
|
149
|
+
ticks = [
|
|
150
|
+
{ label: this.formatStdDev(-4), value: this.stdDev(-4) },
|
|
151
|
+
{ label: "-3σ", value: this.stdDev(-3) },
|
|
152
|
+
{ label: "-2σ", value: this.stdDev(-2) },
|
|
153
|
+
{ label: "-1σ", value: this.stdDev(-1) },
|
|
154
|
+
{ label: this.formatStdDev(0), value: this.stdDev(0) },
|
|
155
|
+
{ label: "+1σ", value: this.stdDev(1) },
|
|
156
|
+
{ label: "+2σ", value: this.stdDev(2) },
|
|
157
|
+
{ label: "+3σ", value: this.stdDev(3) },
|
|
158
|
+
{ label: this.formatStdDev(4), value: this.stdDev(4) }
|
|
159
|
+
];
|
|
160
|
+
break;
|
|
161
|
+
case "min_max":
|
|
162
|
+
default:
|
|
163
|
+
ticks = [
|
|
164
|
+
{ label: this.formatQ(0), value: this.quartile(0) },
|
|
165
|
+
{ label: this.formatQ(1), value: this.quartile(1) },
|
|
166
|
+
{ label: this.formatQ(2), value: this.quartile(2) },
|
|
167
|
+
{ label: this.formatQ(3), value: this.quartile(3) },
|
|
168
|
+
{ label: this.formatQ(4), value: this.quartile(4) }
|
|
169
|
+
];
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
const [domainLow, domainHigh] = this.domain(this._selectElement.node().value);
|
|
173
|
+
return ticks
|
|
174
|
+
.filter(sd => sd.value >= domainLow && sd.value <= domainHigh)
|
|
175
|
+
.map(sd => ({ label: sd.label, value: sd.value.toString() }))
|
|
176
|
+
;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
updateScatter() {
|
|
180
|
+
const mode = this._selectElement.node().value;
|
|
181
|
+
const [domainLow, domainHigh] = this.domain(mode);
|
|
182
|
+
const padding = (domainHigh - domainLow) * (this.domainPadding() / 100);
|
|
183
|
+
|
|
184
|
+
this._bellCurve
|
|
185
|
+
.xAxisDomainLow(domainLow - padding)
|
|
186
|
+
.xAxisDomainHigh(domainHigh + padding)
|
|
187
|
+
.xAxisTicks(this.bellTicks(mode))
|
|
188
|
+
.data([
|
|
189
|
+
[this.stdDev(-4), 0],
|
|
190
|
+
[this.stdDev(-3), 0.3],
|
|
191
|
+
[this.stdDev(-2), 5],
|
|
192
|
+
[this.stdDev(-1), 68],
|
|
193
|
+
[this.stdDev(0), 100],
|
|
194
|
+
[this.stdDev(1), 68],
|
|
195
|
+
[this.stdDev(2), 5],
|
|
196
|
+
[this.stdDev(3), 0.3],
|
|
197
|
+
[this.stdDev(4), 0]
|
|
198
|
+
])
|
|
199
|
+
.resize({ width: this.width(), height: this.height() - this.candleHeight() })
|
|
200
|
+
.render()
|
|
201
|
+
;
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
updateCandle() {
|
|
205
|
+
const candleX = this._bellCurve.dataPos(this.quartile(0));
|
|
206
|
+
const candleW = this._bellCurve.dataPos(this.quartile(4)) - candleX;
|
|
207
|
+
this._candle
|
|
208
|
+
.resize({ width: this.width(), height: this.candleHeight() })
|
|
209
|
+
.pos({ x: (candleX + candleW / 2) + 2, y: this.candleHeight() / 2 })
|
|
210
|
+
.width(candleW)
|
|
211
|
+
.candleWidth(this.candleHeight())
|
|
212
|
+
.data(this.quartiles())
|
|
213
|
+
.render()
|
|
214
|
+
;
|
|
215
|
+
}
|
|
216
|
+
|
|
217
|
+
update(domNode, element) {
|
|
218
|
+
super.update(domNode, element);
|
|
219
|
+
this._tickFormatter = myFormatter(this.tickFormat());
|
|
220
|
+
this._selectElement.node().value = this.view();
|
|
221
|
+
this.updateScatter();
|
|
222
|
+
this.updateCandle();
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
exit(domNode, element) {
|
|
226
|
+
this._bellCurve.target(null);
|
|
227
|
+
this._candle.target(null);
|
|
228
|
+
this._selectElement.remove();
|
|
229
|
+
|
|
230
|
+
super.exit(domNode, element);
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
StatChart.prototype._class += " chart_StatChart";
|
|
234
|
+
|
|
235
|
+
export interface StatChart {
|
|
236
|
+
view(): StatChartView;
|
|
237
|
+
view(_: StatChartView): this;
|
|
238
|
+
|
|
239
|
+
tickFormat(): string;
|
|
240
|
+
tickFormat(_: string): this;
|
|
241
|
+
candleHeight(): number;
|
|
242
|
+
candleHeight(_: number): this;
|
|
243
|
+
domainPadding(): number;
|
|
244
|
+
domainPadding(_: number): this;
|
|
245
|
+
|
|
246
|
+
mean(): number;
|
|
247
|
+
mean(_: number): this;
|
|
248
|
+
standardDeviation(): number;
|
|
249
|
+
standardDeviation(_: number): this;
|
|
250
|
+
quartiles(): Quartiles;
|
|
251
|
+
quartiles(_: Quartiles): this;
|
|
252
|
+
}
|
|
253
|
+
StatChart.prototype.publish("view", "min_max", "set", "View", ["min_max", "25_75", "normal"]);
|
|
254
|
+
|
|
255
|
+
StatChart.prototype.publish("tickFormat", ".2e", "string", "X-Axis Tick Format");
|
|
256
|
+
StatChart.prototype.publish("candleHeight", 20, "number", "Height of candle widget (pixels)");
|
|
257
|
+
StatChart.prototype.publish("domainPadding", 10, "number", "Domain value padding");
|
|
258
|
+
|
|
259
|
+
StatChart.prototype.publish("mean", .5, "number", "Mean");
|
|
260
|
+
StatChart.prototype.publish("standardDeviation", .125, "number", "Standard Deviation (σ)");
|
|
261
|
+
StatChart.prototype.publish("quartiles", [0, .25, .5, .75, 1], "object", "Quartiles (Min, 25%, 50%, 75%, Max)");
|