@hpcc-js/form 3.4.1 → 3.4.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/src/Slider.ts CHANGED
@@ -1,385 +1,385 @@
1
- import { IInput } from "@hpcc-js/api";
2
- import { d3Event, select as d3Select, SVGWidget } from "@hpcc-js/common";
3
- import { drag as d3Drag } from "d3-drag";
4
- import { format as d3Format } from "d3-format";
5
- import { scaleLinear as d3ScaleLinear } from "d3-scale";
6
- import { timeFormat as d3TimeFormat, timeParse as d3TimeParse } from "d3-time-format";
7
-
8
- import "../src/Slider.css";
9
-
10
- export class Slider extends SVGWidget {
11
- xScale;
12
-
13
- moveMode: "both" | "left" | "right";
14
- moveStartPos: number;
15
-
16
- prevValue;
17
-
18
- slider;
19
-
20
- handleLeft;
21
- handleLeftPos: number = 0;
22
- handleLeftStartPos: number;
23
-
24
- handleRight;
25
- handleRightPos: number = 0;
26
- handleRightStartPos: number;
27
-
28
- constructor() {
29
- super();
30
- IInput.call(this);
31
- }
32
-
33
- enter(domNode, element) {
34
- super.enter(domNode, element);
35
- this.resize({ width: this.width(), height: 50 });
36
-
37
- this.xScale = d3ScaleLinear()
38
- .clamp(true);
39
-
40
- this.slider = element.append("g")
41
- .attr("class", "slider")
42
- ;
43
- if (this.low() === null && this.high() === null) {
44
- if (this.lowDatetime() !== null && this.highDatetime() !== null) {
45
- const time_parser = d3TimeParse(this.timePattern() ? this.timePattern() : "%Q");
46
- this.low(time_parser(this.lowDatetime()).getTime());
47
- this.high(time_parser(this.highDatetime()).getTime());
48
- }
49
- }
50
- this.slider.append("line")
51
- .attr("class", "track")
52
- .select(function () { return this.parentNode.appendChild(this.cloneNode(true)); })
53
- .attr("class", "track-inset")
54
- .select(function () { return this.parentNode.appendChild(this.cloneNode(true)); })
55
- .attr("class", "track-overlay")
56
- .call(d3Drag()
57
- .on("start", () => {
58
- const event = d3Event();
59
- this.moveStartPos = event.x;
60
- this.handleLeftStartPos = this.handleLeftPos;
61
- this.handleRightStartPos = this.handleRightPos;
62
- if (this.allowRange() && this.handleLeftPos <= event.x && event.x <= this.handleRightPos) {
63
- this.moveMode = "both";
64
- } else if (Math.abs(event.x - this.handleLeftPos) < Math.abs(event.x - this.handleRightPos)) {
65
- this.moveMode = "left";
66
- } else {
67
- this.moveMode = "right";
68
- }
69
- this.moveHandleTo(event.x);
70
- })
71
- .on("drag", () => {
72
- this.moveHandleTo(d3Event().x);
73
- })
74
- .on("end", () => {
75
- this.moveHandleTo(d3Event().x);
76
- this.data([[this.xScale.invert(this.handleLeftPos), this.xScale.invert(this.handleRightPos)]]);
77
- this.checkChangedValue();
78
- }));
79
-
80
- this.slider.insert("g", ".track-overlay")
81
- .attr("class", "ticks")
82
- .attr("transform", `translate(0, ${this.fontSize() + (this.tickHeight() / 2)})`)
83
- ;
84
-
85
- this.handleRight = this.slider.insert("path", ".track-overlay")
86
- .attr("class", "handle")
87
- ;
88
-
89
- this.handleLeft = this.slider.insert("path", ".track-overlay")
90
- .attr("class", "handle")
91
- ;
92
- }
93
-
94
- update(domNode, element) {
95
- super.update(domNode, element);
96
- const context = this;
97
- this.xScale
98
- .domain([this.low(), this.high()])
99
- .range([0, this.width() - this.padding() * 2])
100
- ;
101
-
102
- this.slider
103
- .attr("transform", "translate(" + (-this.width() / 2 + this.padding()) + "," + 0 + ")");
104
-
105
- this.slider.selectAll("line.track,line.track-inset,line.track-overlay")
106
- .attr("x1", this.xScale.range()[0])
107
- .attr("x2", this.xScale.range()[1])
108
- ;
109
-
110
- const x_distance = (this.width() - (this.padding() * 2)) / (this.tickCount() - 1);
111
-
112
- const tick_text_arr = [];
113
- if (this.tickDateFormat() !== null && this.timePattern() !== null) {
114
- const Q_parser = d3TimeParse("%Q");
115
- const time_formatter = d3TimeFormat(this.tickDateFormat());
116
- const time_segment = (this.high() - this.low()) / (this.tickCount() - 1);
117
- for (let i = 0; i < this.tickCount(); i++) {
118
- const date_to_parse = "" + (this.low() + (time_segment * i));
119
- const parsed_date = Q_parser(date_to_parse);
120
- tick_text_arr.push(time_formatter(parsed_date));
121
- }
122
- } else {
123
- const value_formatter = d3Format(this.tickValueFormat());
124
- const value_segment = (this.high() - this.low()) / (this.tickCount() - 1);
125
- for (let i = 0; i < this.tickCount(); i++) {
126
- const tick_value = this.low() + (value_segment * i);
127
- tick_text_arr.push(value_formatter(tick_value));
128
- }
129
- }
130
- const tickText = this.slider.selectAll("g.tick").data(tick_text_arr);
131
- const tickTextEnter = tickText.enter().append("g").attr("class", "tick");
132
-
133
- tickTextEnter.append("text").attr("class", "tick-text");
134
- tickTextEnter.append("line").attr("class", "tick-line");
135
- tickTextEnter
136
- .merge(tickText)
137
- .each(function (d, i) {
138
- const x = x_distance * i;
139
-
140
- d3Select(this).select("text.tick-text")
141
- .style("font-size", context.fontSize())
142
- .attr("x", function () {
143
- if (i === 0) return x - 2;
144
- return i === context.tickCount() - 1 ? x + 2 : x;
145
- })
146
- .attr("y", context.tickHeight() + (context.tickOffset() / 2) + context.fontSize())
147
- .attr("text-basline", "text-before-edge")
148
- .attr("text-anchor", function () {
149
- if (i === 0) return "start";
150
- return i === context.tickCount() - 1 ? "end" : "middle";
151
- })
152
- .text(() => d)
153
- ;
154
-
155
- d3Select(this).select("line.tick-line")
156
- .attr("x1", x)
157
- .attr("x2", x)
158
- .attr("y1", context.tickOffset() - 1)
159
- .attr("y2", context.tickOffset() + context.tickHeight())
160
- .style("stroke", "#000")
161
- .style("stroke-width", 1)
162
- ;
163
- });
164
- this.slider.node().appendChild(this.handleRight.node());
165
- this.slider.node().appendChild(this.handleLeft.node());
166
- this.handleLeftPos = this.lowPos();
167
- this.handleRightPos = this.highPos();
168
- this.updateHandles();
169
- this.checkChangedValue();
170
- }
171
-
172
- checkChangedValue() {
173
- if (this.prevValue !== this.value() && typeof this.prevValue !== "undefined") {
174
- this.change(this);
175
- }
176
- this.prevValue = this.value();
177
- }
178
-
179
- updateHandles() {
180
- this.handleLeft
181
- .attr("transform", `translate(${this.handleLeftPos}, -28)`)
182
- .attr("d", (d) => this.handlePath("l"))
183
- ;
184
- this.handleRight
185
- .attr("transform", `translate(${this.handleRightPos}, -28)`)
186
- .attr("d", (d) => this.handlePath("r"))
187
- ;
188
- }
189
-
190
- lowPos(): number {
191
- let data = [[this.low(), this.high()]];
192
- if (this.data().length > 0 && typeof this.data()[0][0] === "number" && typeof this.data()[0][1] === "number") {
193
- data = this.data();
194
- }
195
- return this.xScale(data[0][0]);
196
- }
197
-
198
- highPos(): number {
199
- let data = [[this.low(), this.high()]];
200
- if (this.data().length > 0 && typeof this.data()[0][0] === "number" && typeof this.data()[0][1] === "number") {
201
- data = this.data();
202
- }
203
- return this.xScale(data[0][this.allowRange() ? 1 : 0]);
204
- }
205
-
206
- moveHandleTo(pos) {
207
- if (this.allowRange()) {
208
- switch (this.moveMode) {
209
- case "both":
210
- this.handleLeftPos = this.handleLeftStartPos + pos - this.moveStartPos;
211
- this.handleRightPos = this.handleRightStartPos + pos - this.moveStartPos;
212
- break;
213
- case "left":
214
- this.handleLeftPos = pos;
215
- if (this.handleLeftPos > this.handleRightPos) {
216
- this.handleRightPos = this.handleLeftPos;
217
- }
218
- break;
219
- case "right":
220
- this.handleRightPos = pos;
221
- if (this.handleRightPos < this.handleLeftPos) {
222
- this.handleLeftPos = this.handleRightPos;
223
- }
224
- break;
225
- }
226
- } else {
227
- this.handleLeftPos = this.handleRightPos = pos;
228
- }
229
-
230
- this.handleLeftPos = this.constrain(this.handleLeftPos);
231
- this.handleRightPos = this.constrain(this.handleRightPos);
232
- this.value(this.allowRange() ? [this.xScale.invert(this.handleLeftPos), this.xScale.invert(this.handleRightPos)] : this.xScale.invert(this.handleLeftPos));
233
- this.updateHandles();
234
- }
235
-
236
- constrain(pos: number): number {
237
- const range = this.xScale.range();
238
- if (pos < range[0]) pos = range[0];
239
- if (pos > range[1]) pos = range[1];
240
- return this.nearestStep(pos);
241
- }
242
-
243
- nearestStep(pos) {
244
- const value = this.xScale.invert(pos);
245
- return this.xScale(this.low() + Math.round((value - this.low()) / this.step()) * this.step());
246
- }
247
-
248
- handlePath = function (d) {
249
- const e = +(d === "r");
250
- const x = e ? 1 : -1;
251
- const xOffset = this.allowRange() ? 0.5 : 0.0;
252
- const y = 18;
253
- let retVal = "M" + (xOffset * x) + "," + y +
254
- "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6) +
255
- "V" + (2 * y - 6) +
256
- "A6,6 0 0 " + e + " " + (xOffset * x) + "," + (2 * y)
257
- ;
258
- if (this.allowRange()) {
259
- retVal += "Z" +
260
- "M" + (2.5 * x) + "," + (y + 8) +
261
- "V" + (2 * y - 8) +
262
- "M" + (4.5 * x) + "," + (y + 8) +
263
- "V" + (2 * y - 8)
264
- ;
265
- } else {
266
- retVal += "M" + (1 * x) + "," + (y + 8) +
267
- "V" + (2 * y - 8)
268
- ;
269
- }
270
- return retVal;
271
- };
272
-
273
- }
274
- Slider.prototype._class += " form_Slider";
275
- Slider.prototype.implements(IInput.prototype);
276
-
277
- export interface Slider {
278
- // IInput ---
279
- name(): string;
280
- name(_: string): this;
281
- change(_: Slider): void;
282
-
283
- // Properties ---
284
- padding(): number;
285
- padding(_: number): this;
286
- fontSize(): number;
287
- fontSize(_: number): this;
288
- fontFamily(): string;
289
- fontFamily(_: string): this;
290
- fontColor(): string;
291
- fontColor(_: string): this;
292
- allowRange(): boolean;
293
- allowRange(_: boolean): this;
294
- low(): number;
295
- low(_: number): this;
296
- high(): number;
297
- high(_: number): this;
298
- step(): number;
299
- step(_: number): this;
300
- lowDatetime(): string;
301
- lowDatetime(_: string): this;
302
- highDatetime(): string;
303
- highDatetime(_: string): this;
304
- stepDatetime(): number;
305
- stepDatetime(_: number): this;
306
- selectionLabel(): string;
307
- selectionLabel(_: string): this;
308
- label(): string;
309
- label(_: string): this;
310
- value(): any;
311
- value(_: any): this;
312
- validate(): string;
313
- validate(_: string): this;
314
- tickCount(): number;
315
- tickCount(_: number): this;
316
- tickOffset(): number;
317
- tickOffset(_: number): this;
318
- tickHeight(): number;
319
- tickHeight(_: number): this;
320
- tickDateFormat(): string;
321
- tickDateFormat(_: string): this;
322
- tickValueFormat(): string;
323
- tickValueFormat(_: string): this;
324
- timePattern(): string;
325
- timePattern(_: string): this;
326
-
327
- padding_exists(): boolean;
328
- fontSize_exists(): boolean;
329
- fontFamily_exists(): boolean;
330
- fontColor_exists(): boolean;
331
- allowRange_exists(): boolean;
332
- low_exists(): boolean;
333
- step_exists(): boolean;
334
- high_exists(): boolean;
335
- selectionLabel_exists(): boolean;
336
- name_exists(): boolean;
337
- label_exists(): boolean;
338
- value_exists(): boolean;
339
- validate_exists(): boolean;
340
- }
341
-
342
- Slider.prototype.publish("padding", 16, "number", "Outer Padding", null, { tags: ["Basic"] });
343
- Slider.prototype.publish("fontSize", 12, "number", "Font Size", null, { tags: ["Basic"] });
344
- Slider.prototype.publish("fontFamily", null, "string", "Font Name", null, { tags: ["Basic"] });
345
- Slider.prototype.publish("fontColor", null, "html-color", "Font Color", null, { tags: ["Basic"] });
346
-
347
- Slider.prototype.publish("allowRange", false, "boolean", "Allow Range Selection", null, { tags: ["Intermediate"] });
348
- Slider.prototype.publish("low", null, "number", "Low", null, { tags: ["Intermediate"] });
349
- Slider.prototype.publish("high", null, "number", "High", null, { tags: ["Intermediate"] });
350
- Slider.prototype.publish("step", 10, "number", "Step", null, { tags: ["Intermediate"] });
351
- Slider.prototype.publish("lowDatetime", null, "string", "Low", null, { tags: ["Intermediate"] });
352
- Slider.prototype.publish("highDatetime", null, "string", "High", null, { tags: ["Intermediate"] });
353
- Slider.prototype.publish("selectionLabel", "", "string", "Selection Label", null, { tags: ["Intermediate"] });
354
-
355
- Slider.prototype.publish("timePattern", "%Y-%m-%d", "string");
356
-
357
- Slider.prototype.publish("tickCount", 10, "number");
358
- Slider.prototype.publish("tickOffset", 5, "number");
359
- Slider.prototype.publish("tickHeight", 8, "number");
360
- Slider.prototype.publish("tickDateFormat", null, "string");
361
- Slider.prototype.publish("tickValueFormat", ",.0f", "string");
362
-
363
- const name = Slider.prototype.name;
364
- Slider.prototype.name = function (_?: any): any {
365
- const retVal = name.apply(this, arguments);
366
- if (arguments.length) {
367
- const val = _ instanceof Array ? _ : [_];
368
- SVGWidget.prototype.columns.call(this, val);
369
- }
370
- return retVal;
371
- };
372
-
373
- const value = Slider.prototype.value;
374
- Slider.prototype.value = function (_?: any): any {
375
- const retVal = value.apply(this, arguments);
376
- if (!arguments.length) {
377
- if (!this.allowRange()) {
378
- return SVGWidget.prototype.data.call(this)[0][0];
379
- }
380
- return SVGWidget.prototype.data.call(this)[0];
381
- } else {
382
- SVGWidget.prototype.data.call(this, [this.allowRange() ? _ : [_, _]]);
383
- }
384
- return retVal;
385
- };
1
+ import { IInput } from "@hpcc-js/api";
2
+ import { d3Event, select as d3Select, SVGWidget } from "@hpcc-js/common";
3
+ import { drag as d3Drag } from "d3-drag";
4
+ import { format as d3Format } from "d3-format";
5
+ import { scaleLinear as d3ScaleLinear } from "d3-scale";
6
+ import { timeFormat as d3TimeFormat, timeParse as d3TimeParse } from "d3-time-format";
7
+
8
+ import "../src/Slider.css";
9
+
10
+ export class Slider extends SVGWidget {
11
+ xScale;
12
+
13
+ moveMode: "both" | "left" | "right";
14
+ moveStartPos: number;
15
+
16
+ prevValue;
17
+
18
+ slider;
19
+
20
+ handleLeft;
21
+ handleLeftPos: number = 0;
22
+ handleLeftStartPos: number;
23
+
24
+ handleRight;
25
+ handleRightPos: number = 0;
26
+ handleRightStartPos: number;
27
+
28
+ constructor() {
29
+ super();
30
+ IInput.call(this);
31
+ }
32
+
33
+ enter(domNode, element) {
34
+ super.enter(domNode, element);
35
+ this.resize({ width: this.width(), height: 50 });
36
+
37
+ this.xScale = d3ScaleLinear()
38
+ .clamp(true);
39
+
40
+ this.slider = element.append("g")
41
+ .attr("class", "slider")
42
+ ;
43
+ if (this.low() === null && this.high() === null) {
44
+ if (this.lowDatetime() !== null && this.highDatetime() !== null) {
45
+ const time_parser = d3TimeParse(this.timePattern() ? this.timePattern() : "%Q");
46
+ this.low(time_parser(this.lowDatetime()).getTime());
47
+ this.high(time_parser(this.highDatetime()).getTime());
48
+ }
49
+ }
50
+ this.slider.append("line")
51
+ .attr("class", "track")
52
+ .select(function () { return this.parentNode.appendChild(this.cloneNode(true)); })
53
+ .attr("class", "track-inset")
54
+ .select(function () { return this.parentNode.appendChild(this.cloneNode(true)); })
55
+ .attr("class", "track-overlay")
56
+ .call(d3Drag()
57
+ .on("start", () => {
58
+ const event = d3Event();
59
+ this.moveStartPos = event.x;
60
+ this.handleLeftStartPos = this.handleLeftPos;
61
+ this.handleRightStartPos = this.handleRightPos;
62
+ if (this.allowRange() && this.handleLeftPos <= event.x && event.x <= this.handleRightPos) {
63
+ this.moveMode = "both";
64
+ } else if (Math.abs(event.x - this.handleLeftPos) < Math.abs(event.x - this.handleRightPos)) {
65
+ this.moveMode = "left";
66
+ } else {
67
+ this.moveMode = "right";
68
+ }
69
+ this.moveHandleTo(event.x);
70
+ })
71
+ .on("drag", () => {
72
+ this.moveHandleTo(d3Event().x);
73
+ })
74
+ .on("end", () => {
75
+ this.moveHandleTo(d3Event().x);
76
+ this.data([[this.xScale.invert(this.handleLeftPos), this.xScale.invert(this.handleRightPos)]]);
77
+ this.checkChangedValue();
78
+ }));
79
+
80
+ this.slider.insert("g", ".track-overlay")
81
+ .attr("class", "ticks")
82
+ .attr("transform", `translate(0, ${this.fontSize() + (this.tickHeight() / 2)})`)
83
+ ;
84
+
85
+ this.handleRight = this.slider.insert("path", ".track-overlay")
86
+ .attr("class", "handle")
87
+ ;
88
+
89
+ this.handleLeft = this.slider.insert("path", ".track-overlay")
90
+ .attr("class", "handle")
91
+ ;
92
+ }
93
+
94
+ update(domNode, element) {
95
+ super.update(domNode, element);
96
+ const context = this;
97
+ this.xScale
98
+ .domain([this.low(), this.high()])
99
+ .range([0, this.width() - this.padding() * 2])
100
+ ;
101
+
102
+ this.slider
103
+ .attr("transform", "translate(" + (-this.width() / 2 + this.padding()) + "," + 0 + ")");
104
+
105
+ this.slider.selectAll("line.track,line.track-inset,line.track-overlay")
106
+ .attr("x1", this.xScale.range()[0])
107
+ .attr("x2", this.xScale.range()[1])
108
+ ;
109
+
110
+ const x_distance = (this.width() - (this.padding() * 2)) / (this.tickCount() - 1);
111
+
112
+ const tick_text_arr = [];
113
+ if (this.tickDateFormat() !== null && this.timePattern() !== null) {
114
+ const Q_parser = d3TimeParse("%Q");
115
+ const time_formatter = d3TimeFormat(this.tickDateFormat());
116
+ const time_segment = (this.high() - this.low()) / (this.tickCount() - 1);
117
+ for (let i = 0; i < this.tickCount(); i++) {
118
+ const date_to_parse = "" + (this.low() + (time_segment * i));
119
+ const parsed_date = Q_parser(date_to_parse);
120
+ tick_text_arr.push(time_formatter(parsed_date));
121
+ }
122
+ } else {
123
+ const value_formatter = d3Format(this.tickValueFormat());
124
+ const value_segment = (this.high() - this.low()) / (this.tickCount() - 1);
125
+ for (let i = 0; i < this.tickCount(); i++) {
126
+ const tick_value = this.low() + (value_segment * i);
127
+ tick_text_arr.push(value_formatter(tick_value));
128
+ }
129
+ }
130
+ const tickText = this.slider.selectAll("g.tick").data(tick_text_arr);
131
+ const tickTextEnter = tickText.enter().append("g").attr("class", "tick");
132
+
133
+ tickTextEnter.append("text").attr("class", "tick-text");
134
+ tickTextEnter.append("line").attr("class", "tick-line");
135
+ tickTextEnter
136
+ .merge(tickText)
137
+ .each(function (d, i) {
138
+ const x = x_distance * i;
139
+
140
+ d3Select(this).select("text.tick-text")
141
+ .style("font-size", context.fontSize())
142
+ .attr("x", function () {
143
+ if (i === 0) return x - 2;
144
+ return i === context.tickCount() - 1 ? x + 2 : x;
145
+ })
146
+ .attr("y", context.tickHeight() + (context.tickOffset() / 2) + context.fontSize())
147
+ .attr("text-basline", "text-before-edge")
148
+ .attr("text-anchor", function () {
149
+ if (i === 0) return "start";
150
+ return i === context.tickCount() - 1 ? "end" : "middle";
151
+ })
152
+ .text(() => d)
153
+ ;
154
+
155
+ d3Select(this).select("line.tick-line")
156
+ .attr("x1", x)
157
+ .attr("x2", x)
158
+ .attr("y1", context.tickOffset() - 1)
159
+ .attr("y2", context.tickOffset() + context.tickHeight())
160
+ .style("stroke", "#000")
161
+ .style("stroke-width", 1)
162
+ ;
163
+ });
164
+ this.slider.node().appendChild(this.handleRight.node());
165
+ this.slider.node().appendChild(this.handleLeft.node());
166
+ this.handleLeftPos = this.lowPos();
167
+ this.handleRightPos = this.highPos();
168
+ this.updateHandles();
169
+ this.checkChangedValue();
170
+ }
171
+
172
+ checkChangedValue() {
173
+ if (this.prevValue !== this.value() && typeof this.prevValue !== "undefined") {
174
+ this.change(this);
175
+ }
176
+ this.prevValue = this.value();
177
+ }
178
+
179
+ updateHandles() {
180
+ this.handleLeft
181
+ .attr("transform", `translate(${this.handleLeftPos}, -28)`)
182
+ .attr("d", (d) => this.handlePath("l"))
183
+ ;
184
+ this.handleRight
185
+ .attr("transform", `translate(${this.handleRightPos}, -28)`)
186
+ .attr("d", (d) => this.handlePath("r"))
187
+ ;
188
+ }
189
+
190
+ lowPos(): number {
191
+ let data = [[this.low(), this.high()]];
192
+ if (this.data().length > 0 && typeof this.data()[0][0] === "number" && typeof this.data()[0][1] === "number") {
193
+ data = this.data();
194
+ }
195
+ return this.xScale(data[0][0]);
196
+ }
197
+
198
+ highPos(): number {
199
+ let data = [[this.low(), this.high()]];
200
+ if (this.data().length > 0 && typeof this.data()[0][0] === "number" && typeof this.data()[0][1] === "number") {
201
+ data = this.data();
202
+ }
203
+ return this.xScale(data[0][this.allowRange() ? 1 : 0]);
204
+ }
205
+
206
+ moveHandleTo(pos) {
207
+ if (this.allowRange()) {
208
+ switch (this.moveMode) {
209
+ case "both":
210
+ this.handleLeftPos = this.handleLeftStartPos + pos - this.moveStartPos;
211
+ this.handleRightPos = this.handleRightStartPos + pos - this.moveStartPos;
212
+ break;
213
+ case "left":
214
+ this.handleLeftPos = pos;
215
+ if (this.handleLeftPos > this.handleRightPos) {
216
+ this.handleRightPos = this.handleLeftPos;
217
+ }
218
+ break;
219
+ case "right":
220
+ this.handleRightPos = pos;
221
+ if (this.handleRightPos < this.handleLeftPos) {
222
+ this.handleLeftPos = this.handleRightPos;
223
+ }
224
+ break;
225
+ }
226
+ } else {
227
+ this.handleLeftPos = this.handleRightPos = pos;
228
+ }
229
+
230
+ this.handleLeftPos = this.constrain(this.handleLeftPos);
231
+ this.handleRightPos = this.constrain(this.handleRightPos);
232
+ this.value(this.allowRange() ? [this.xScale.invert(this.handleLeftPos), this.xScale.invert(this.handleRightPos)] : this.xScale.invert(this.handleLeftPos));
233
+ this.updateHandles();
234
+ }
235
+
236
+ constrain(pos: number): number {
237
+ const range = this.xScale.range();
238
+ if (pos < range[0]) pos = range[0];
239
+ if (pos > range[1]) pos = range[1];
240
+ return this.nearestStep(pos);
241
+ }
242
+
243
+ nearestStep(pos) {
244
+ const value = this.xScale.invert(pos);
245
+ return this.xScale(this.low() + Math.round((value - this.low()) / this.step()) * this.step());
246
+ }
247
+
248
+ handlePath = function (d) {
249
+ const e = +(d === "r");
250
+ const x = e ? 1 : -1;
251
+ const xOffset = this.allowRange() ? 0.5 : 0.0;
252
+ const y = 18;
253
+ let retVal = "M" + (xOffset * x) + "," + y +
254
+ "A6,6 0 0 " + e + " " + (6.5 * x) + "," + (y + 6) +
255
+ "V" + (2 * y - 6) +
256
+ "A6,6 0 0 " + e + " " + (xOffset * x) + "," + (2 * y)
257
+ ;
258
+ if (this.allowRange()) {
259
+ retVal += "Z" +
260
+ "M" + (2.5 * x) + "," + (y + 8) +
261
+ "V" + (2 * y - 8) +
262
+ "M" + (4.5 * x) + "," + (y + 8) +
263
+ "V" + (2 * y - 8)
264
+ ;
265
+ } else {
266
+ retVal += "M" + (1 * x) + "," + (y + 8) +
267
+ "V" + (2 * y - 8)
268
+ ;
269
+ }
270
+ return retVal;
271
+ };
272
+
273
+ }
274
+ Slider.prototype._class += " form_Slider";
275
+ Slider.prototype.implements(IInput.prototype);
276
+
277
+ export interface Slider {
278
+ // IInput ---
279
+ name(): string;
280
+ name(_: string): this;
281
+ change(_: Slider): void;
282
+
283
+ // Properties ---
284
+ padding(): number;
285
+ padding(_: number): this;
286
+ fontSize(): number;
287
+ fontSize(_: number): this;
288
+ fontFamily(): string;
289
+ fontFamily(_: string): this;
290
+ fontColor(): string;
291
+ fontColor(_: string): this;
292
+ allowRange(): boolean;
293
+ allowRange(_: boolean): this;
294
+ low(): number;
295
+ low(_: number): this;
296
+ high(): number;
297
+ high(_: number): this;
298
+ step(): number;
299
+ step(_: number): this;
300
+ lowDatetime(): string;
301
+ lowDatetime(_: string): this;
302
+ highDatetime(): string;
303
+ highDatetime(_: string): this;
304
+ stepDatetime(): number;
305
+ stepDatetime(_: number): this;
306
+ selectionLabel(): string;
307
+ selectionLabel(_: string): this;
308
+ label(): string;
309
+ label(_: string): this;
310
+ value(): any;
311
+ value(_: any): this;
312
+ validate(): string;
313
+ validate(_: string): this;
314
+ tickCount(): number;
315
+ tickCount(_: number): this;
316
+ tickOffset(): number;
317
+ tickOffset(_: number): this;
318
+ tickHeight(): number;
319
+ tickHeight(_: number): this;
320
+ tickDateFormat(): string;
321
+ tickDateFormat(_: string): this;
322
+ tickValueFormat(): string;
323
+ tickValueFormat(_: string): this;
324
+ timePattern(): string;
325
+ timePattern(_: string): this;
326
+
327
+ padding_exists(): boolean;
328
+ fontSize_exists(): boolean;
329
+ fontFamily_exists(): boolean;
330
+ fontColor_exists(): boolean;
331
+ allowRange_exists(): boolean;
332
+ low_exists(): boolean;
333
+ step_exists(): boolean;
334
+ high_exists(): boolean;
335
+ selectionLabel_exists(): boolean;
336
+ name_exists(): boolean;
337
+ label_exists(): boolean;
338
+ value_exists(): boolean;
339
+ validate_exists(): boolean;
340
+ }
341
+
342
+ Slider.prototype.publish("padding", 16, "number", "Outer Padding", null, { tags: ["Basic"] });
343
+ Slider.prototype.publish("fontSize", 12, "number", "Font Size", null, { tags: ["Basic"] });
344
+ Slider.prototype.publish("fontFamily", null, "string", "Font Name", null, { tags: ["Basic"] });
345
+ Slider.prototype.publish("fontColor", null, "html-color", "Font Color", null, { tags: ["Basic"] });
346
+
347
+ Slider.prototype.publish("allowRange", false, "boolean", "Allow Range Selection", null, { tags: ["Intermediate"] });
348
+ Slider.prototype.publish("low", null, "number", "Low", null, { tags: ["Intermediate"] });
349
+ Slider.prototype.publish("high", null, "number", "High", null, { tags: ["Intermediate"] });
350
+ Slider.prototype.publish("step", 10, "number", "Step", null, { tags: ["Intermediate"] });
351
+ Slider.prototype.publish("lowDatetime", null, "string", "Low", null, { tags: ["Intermediate"] });
352
+ Slider.prototype.publish("highDatetime", null, "string", "High", null, { tags: ["Intermediate"] });
353
+ Slider.prototype.publish("selectionLabel", "", "string", "Selection Label", null, { tags: ["Intermediate"] });
354
+
355
+ Slider.prototype.publish("timePattern", "%Y-%m-%d", "string");
356
+
357
+ Slider.prototype.publish("tickCount", 10, "number");
358
+ Slider.prototype.publish("tickOffset", 5, "number");
359
+ Slider.prototype.publish("tickHeight", 8, "number");
360
+ Slider.prototype.publish("tickDateFormat", null, "string");
361
+ Slider.prototype.publish("tickValueFormat", ",.0f", "string");
362
+
363
+ const name = Slider.prototype.name;
364
+ Slider.prototype.name = function (_?: any): any {
365
+ const retVal = name.apply(this, arguments);
366
+ if (arguments.length) {
367
+ const val = _ instanceof Array ? _ : [_];
368
+ SVGWidget.prototype.columns.call(this, val);
369
+ }
370
+ return retVal;
371
+ };
372
+
373
+ const value = Slider.prototype.value;
374
+ Slider.prototype.value = function (_?: any): any {
375
+ const retVal = value.apply(this, arguments);
376
+ if (!arguments.length) {
377
+ if (!this.allowRange()) {
378
+ return SVGWidget.prototype.data.call(this)[0][0];
379
+ }
380
+ return SVGWidget.prototype.data.call(this)[0];
381
+ } else {
382
+ SVGWidget.prototype.data.call(this, [this.allowRange() ? _ : [_, _]]);
383
+ }
384
+ return retVal;
385
+ };