@hpcc-js/timeline 3.2.4 → 3.3.1
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/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 +9 -9
- package/src/ReactAxisGanttSeries.ts +3 -0
- package/src/ReactGantt.ts +78 -5
- package/types/ReactAxisGanttSeries.d.ts +2 -0
- package/types/ReactGantt.d.ts +6 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hpcc-js/timeline",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.3.1",
|
|
4
4
|
"description": "hpcc-js - Viz Timeline",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.umd.cjs",
|
|
@@ -37,15 +37,15 @@
|
|
|
37
37
|
"update-major": "npx --yes npm-check-updates -u"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@hpcc-js/api": "^3.4.
|
|
41
|
-
"@hpcc-js/chart": "^3.6.
|
|
42
|
-
"@hpcc-js/common": "^3.6.
|
|
43
|
-
"@hpcc-js/html": "^3.3.
|
|
44
|
-
"@hpcc-js/layout": "^3.
|
|
45
|
-
"@hpcc-js/react": "^3.4.
|
|
40
|
+
"@hpcc-js/api": "^3.4.5",
|
|
41
|
+
"@hpcc-js/chart": "^3.6.1",
|
|
42
|
+
"@hpcc-js/common": "^3.6.1",
|
|
43
|
+
"@hpcc-js/html": "^3.3.5",
|
|
44
|
+
"@hpcc-js/layout": "^3.5.0",
|
|
45
|
+
"@hpcc-js/react": "^3.4.5"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@hpcc-js/esbuild-plugins": "^1.
|
|
48
|
+
"@hpcc-js/esbuild-plugins": "^1.8.0",
|
|
49
49
|
"d3-array": "^1",
|
|
50
50
|
"d3-scale": "^1",
|
|
51
51
|
"d3-selection": "^1",
|
|
@@ -63,5 +63,5 @@
|
|
|
63
63
|
"url": "https://github.com/hpcc-systems/Visualization/issues"
|
|
64
64
|
},
|
|
65
65
|
"homepage": "https://github.com/hpcc-systems/Visualization",
|
|
66
|
-
"gitHead": "
|
|
66
|
+
"gitHead": "4b76aa36763923096cd3ff7afed75e054ea33197"
|
|
67
67
|
}
|
|
@@ -237,6 +237,8 @@ export interface ReactAxisGanttSeries {
|
|
|
237
237
|
bucketColumn(_: string): this;
|
|
238
238
|
maxZoom(): number;
|
|
239
239
|
maxZoom(_: number): this;
|
|
240
|
+
preserveZoom(): boolean;
|
|
241
|
+
preserveZoom(_: boolean): this;
|
|
240
242
|
}
|
|
241
243
|
ReactAxisGanttSeries.prototype.publish("tickFormat", null, "string", "Format rule applied to axis tick labels", undefined, { optional: true });
|
|
242
244
|
ReactAxisGanttSeries.prototype.publish("axisHeight", 22, "number", "Height of axes (pixels)");
|
|
@@ -260,6 +262,7 @@ ReactAxisGanttSeries.prototype.publishProxy("colorColumn", "_gantt");
|
|
|
260
262
|
ReactAxisGanttSeries.prototype.publishProxy("seriesColumn", "_gantt");
|
|
261
263
|
ReactAxisGanttSeries.prototype.publishProxy("bucketColumn", "_gantt");
|
|
262
264
|
ReactAxisGanttSeries.prototype.publishProxy("maxZoom", "_gantt");
|
|
265
|
+
ReactAxisGanttSeries.prototype.publishProxy("preserveZoom", "_gantt");
|
|
263
266
|
ReactAxisGanttSeries.prototype.publishProxy("evenSeriesBackground", "_gantt");
|
|
264
267
|
ReactAxisGanttSeries.prototype.publishProxy("oddSeriesBackground", "_gantt");
|
|
265
268
|
ReactAxisGanttSeries.prototype.publishProxy("bucketHeight", "_gantt");
|
package/src/ReactGantt.ts
CHANGED
|
@@ -36,6 +36,8 @@ export class ReactGantt extends SVGZoomWidget {
|
|
|
36
36
|
public _minStart: number;
|
|
37
37
|
public _maxEnd: number;
|
|
38
38
|
|
|
39
|
+
protected _prevZoomState: { visibleStart: number; visibleEnd: number } | null = null;
|
|
40
|
+
|
|
39
41
|
protected _title_idx = 0;
|
|
40
42
|
protected _startDate_idx = 1;
|
|
41
43
|
protected _endDate_idx = 2;
|
|
@@ -190,12 +192,14 @@ export class ReactGantt extends SVGZoomWidget {
|
|
|
190
192
|
this._buckets = this.calcBuckets(this.data(), this._startDate_idx, this._endDate_idx);
|
|
191
193
|
}
|
|
192
194
|
}
|
|
193
|
-
const interpedStart = this._interpolateX(this._minStart);
|
|
194
195
|
|
|
195
|
-
this.
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
196
|
+
if (!this.preserveZoom() || !this._prevZoomState) {
|
|
197
|
+
const interpedStart = this._interpolateX(this._minStart);
|
|
198
|
+
this.zoomTo(
|
|
199
|
+
[interpedStart, 0],
|
|
200
|
+
1
|
|
201
|
+
);
|
|
202
|
+
}
|
|
199
203
|
|
|
200
204
|
const bucketHeight = this.bucketHeight();
|
|
201
205
|
|
|
@@ -331,6 +335,51 @@ export class ReactGantt extends SVGZoomWidget {
|
|
|
331
335
|
})
|
|
332
336
|
;
|
|
333
337
|
element.on("dblclick.zoom", null);
|
|
338
|
+
|
|
339
|
+
// restore zoom state after all rendering is set up
|
|
340
|
+
if (this.preserveZoom() && this._prevZoomState && this._interpolateX) {
|
|
341
|
+
const width = this.width();
|
|
342
|
+
if (width > 0) {
|
|
343
|
+
const visibleStart = this._minStart;
|
|
344
|
+
const visibleEnd = this._maxEnd;
|
|
345
|
+
const clampedStart = Math.max(visibleStart, Math.min(visibleEnd, this._prevZoomState.visibleStart));
|
|
346
|
+
let clampedEnd = Math.max(visibleStart, Math.min(visibleEnd, this._prevZoomState.visibleEnd));
|
|
347
|
+
if (clampedEnd <= clampedStart) {
|
|
348
|
+
const visibleWidth = visibleEnd - visibleStart;
|
|
349
|
+
const epsilon = visibleWidth * 1e-6 || 1e-6;
|
|
350
|
+
clampedEnd = Math.min(visibleEnd, clampedStart + epsilon);
|
|
351
|
+
}
|
|
352
|
+
const startPixel = this._interpolateX(clampedStart);
|
|
353
|
+
const endPixel = this._interpolateX(clampedEnd);
|
|
354
|
+
const span = endPixel - startPixel;
|
|
355
|
+
if (isFinite(span) && Math.abs(span) > 1e-9) {
|
|
356
|
+
const rawScale = width / span;
|
|
357
|
+
const minScale = 0.05; // must match zoomExtent minimum set at start of update()
|
|
358
|
+
const maxScale = this.maxZoom();
|
|
359
|
+
const targetScale = Math.max(minScale, Math.min(maxScale, rawScale));
|
|
360
|
+
|
|
361
|
+
if (targetScale > 0 && isFinite(targetScale)) {
|
|
362
|
+
const centerPixel = (startPixel + endPixel) / 2;
|
|
363
|
+
const halfViewport = width / (2 * targetScale);
|
|
364
|
+
const x0 = this._interpolateX(visibleStart);
|
|
365
|
+
const x1 = this._interpolateX(visibleEnd);
|
|
366
|
+
|
|
367
|
+
let clampedCenter = centerPixel;
|
|
368
|
+
if (clampedCenter - halfViewport < x0) {
|
|
369
|
+
clampedCenter = x0 + halfViewport;
|
|
370
|
+
}
|
|
371
|
+
if (clampedCenter + halfViewport > x1) {
|
|
372
|
+
clampedCenter = x1 - halfViewport;
|
|
373
|
+
}
|
|
374
|
+
|
|
375
|
+
const translateX = (width / 2) - (targetScale * clampedCenter);
|
|
376
|
+
if (isFinite(translateX)) {
|
|
377
|
+
this.zoomTo([translateX, 0], targetScale);
|
|
378
|
+
}
|
|
379
|
+
}
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
}
|
|
334
383
|
}
|
|
335
384
|
exit(domNode, element) {
|
|
336
385
|
this._tooltip.target(null);
|
|
@@ -442,6 +491,27 @@ export class ReactGantt extends SVGZoomWidget {
|
|
|
442
491
|
public _transform = { k: 1, x: 0, y: 0 };
|
|
443
492
|
zoomed(transform) {
|
|
444
493
|
this._transform = transform;
|
|
494
|
+
// store current visible range for zoom preservation
|
|
495
|
+
if (this._interpolateX && typeof this._interpolateX.invert === "function") {
|
|
496
|
+
const width = this.width();
|
|
497
|
+
if (width > 0 && isFinite(transform.k) && transform.k !== 0) {
|
|
498
|
+
const startPixel = (0 - transform.x) / transform.k;
|
|
499
|
+
const endPixel = (width - transform.x) / transform.k;
|
|
500
|
+
let visibleStart = this._interpolateX.invert(startPixel);
|
|
501
|
+
let visibleEnd = this._interpolateX.invert(endPixel);
|
|
502
|
+
if (isFinite(visibleStart) && isFinite(visibleEnd)) {
|
|
503
|
+
if (visibleStart > visibleEnd) {
|
|
504
|
+
const tmp = visibleStart;
|
|
505
|
+
visibleStart = visibleEnd;
|
|
506
|
+
visibleEnd = tmp;
|
|
507
|
+
}
|
|
508
|
+
this._prevZoomState = {
|
|
509
|
+
visibleStart,
|
|
510
|
+
visibleEnd
|
|
511
|
+
};
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
}
|
|
445
515
|
switch (this.renderMode()) {
|
|
446
516
|
case "scale-all":
|
|
447
517
|
this._zoomScale = transform.k;
|
|
@@ -667,6 +737,8 @@ export interface ReactGantt {
|
|
|
667
737
|
fitWidthToContent(_: boolean): this;
|
|
668
738
|
fitHeightToContent(): boolean;
|
|
669
739
|
fitHeightToContent(_: boolean): this;
|
|
740
|
+
preserveZoom(): boolean;
|
|
741
|
+
preserveZoom(_: boolean): this;
|
|
670
742
|
evenSeriesBackground(): string;
|
|
671
743
|
evenSeriesBackground(_: string): this;
|
|
672
744
|
oddSeriesBackground(): string;
|
|
@@ -675,6 +747,7 @@ export interface ReactGantt {
|
|
|
675
747
|
|
|
676
748
|
ReactGantt.prototype.publish("fitWidthToContent", false, "boolean", "If true, resize will simply reapply the bounding box width");
|
|
677
749
|
ReactGantt.prototype.publish("fitHeightToContent", false, "boolean", "If true, resize will simply reapply the bounding box height");
|
|
750
|
+
ReactGantt.prototype.publish("preserveZoom", false, "boolean", "If true, maintain zoom level when data is updated");
|
|
678
751
|
ReactGantt.prototype.publish("titleColumn", null, "string", "Column name to for the title");
|
|
679
752
|
ReactGantt.prototype.publish("startDateColumn", null, "string", "Column name to for the start date");
|
|
680
753
|
ReactGantt.prototype.publish("endDateColumn", null, "string", "Column name to for the end date");
|
package/types/ReactGantt.d.ts
CHANGED
|
@@ -24,6 +24,10 @@ export declare class ReactGantt extends SVGZoomWidget {
|
|
|
24
24
|
_tooltip: any;
|
|
25
25
|
_minStart: number;
|
|
26
26
|
_maxEnd: number;
|
|
27
|
+
protected _prevZoomState: {
|
|
28
|
+
visibleStart: number;
|
|
29
|
+
visibleEnd: number;
|
|
30
|
+
} | null;
|
|
27
31
|
protected _title_idx: number;
|
|
28
32
|
protected _startDate_idx: number;
|
|
29
33
|
protected _endDate_idx: number;
|
|
@@ -123,6 +127,8 @@ export interface ReactGantt {
|
|
|
123
127
|
fitWidthToContent(_: boolean): this;
|
|
124
128
|
fitHeightToContent(): boolean;
|
|
125
129
|
fitHeightToContent(_: boolean): this;
|
|
130
|
+
preserveZoom(): boolean;
|
|
131
|
+
preserveZoom(_: boolean): this;
|
|
126
132
|
evenSeriesBackground(): string;
|
|
127
133
|
evenSeriesBackground(_: string): this;
|
|
128
134
|
oddSeriesBackground(): string;
|