gantt-task-react-v 1.3.2 → 1.3.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/dist/gantt-task-react.es.js +100 -372
- package/dist/gantt-task-react.umd.js +100 -372
- package/package.json +1 -1
- package/dist/helpers/use-incremental-coordinates.d.ts +0 -17
- package/dist/helpers/use-memory-management.d.ts +0 -122
- package/dist/helpers/use-optimized-data-structures.d.ts +0 -24
- package/dist/helpers/use-optimized-svg-rendering.d.ts +0 -117
- package/dist/helpers/use-performance-monitor.d.ts +0 -106
- package/dist/helpers/use-progressive-loading.d.ts +0 -63
- package/dist/helpers/use-spatial-dependency-map.d.ts +0 -49
- package/dist/helpers/use-web-worker.d.ts +0 -50
|
@@ -11835,29 +11835,45 @@
|
|
|
11835
11835
|
const currentDate = getDateByOffset(startDate, index2, viewMode);
|
|
11836
11836
|
const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
|
|
11837
11837
|
const remainderMillis = xDate.getTime() - currentDate.getTime();
|
|
11838
|
-
const
|
|
11839
|
-
|
|
11838
|
+
const intervalDuration = nextDate.getTime() - currentDate.getTime();
|
|
11839
|
+
const percentOfInterval = intervalDuration === 0 ? 0 : remainderMillis / intervalDuration;
|
|
11840
|
+
const result = index2 * columnWidth + percentOfInterval * columnWidth;
|
|
11841
|
+
return isNaN(result) || !isFinite(result) ? 0 : result;
|
|
11840
11842
|
};
|
|
11841
11843
|
const taskComparisonXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
|
|
11842
11844
|
const index2 = getDatesDiff(xDate, startDate, viewMode);
|
|
11843
11845
|
const currentDate = getDateByOffset(startDate, index2, viewMode);
|
|
11844
11846
|
const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
|
|
11845
11847
|
const remainderMillis = xDate.getTime() - currentDate.getTime();
|
|
11846
|
-
const
|
|
11847
|
-
|
|
11848
|
+
const intervalDuration = nextDate.getTime() - currentDate.getTime();
|
|
11849
|
+
const percentOfInterval = intervalDuration === 0 ? 0 : remainderMillis / intervalDuration;
|
|
11850
|
+
const result = index2 * columnWidth + percentOfInterval * columnWidth;
|
|
11851
|
+
return isNaN(result) || !isFinite(result) ? 0 : result;
|
|
11848
11852
|
};
|
|
11849
11853
|
const progressWithByParams = (taskX1, taskX2, progress, rtl) => {
|
|
11850
|
-
const
|
|
11854
|
+
const safeTaskX1 = isNaN(taskX1) || !isFinite(taskX1) ? 0 : taskX1;
|
|
11855
|
+
const safeTaskX2 = isNaN(taskX2) || !isFinite(taskX2) ? 0 : taskX2;
|
|
11856
|
+
const safeProgress = isNaN(progress) || !isFinite(progress) ? 0 : progress;
|
|
11857
|
+
const progressWidth = Math.max(
|
|
11858
|
+
(safeTaskX2 - safeTaskX1) * safeProgress * 0.01,
|
|
11859
|
+
0
|
|
11860
|
+
);
|
|
11851
11861
|
let progressX;
|
|
11852
11862
|
if (rtl) {
|
|
11853
|
-
progressX =
|
|
11863
|
+
progressX = safeTaskX2 - progressWidth;
|
|
11854
11864
|
} else {
|
|
11855
|
-
progressX =
|
|
11865
|
+
progressX = safeTaskX1;
|
|
11856
11866
|
}
|
|
11857
11867
|
return [progressWidth, progressX];
|
|
11858
11868
|
};
|
|
11859
11869
|
const dateByX = (x, taskX, taskDate, xStep, timeStep) => {
|
|
11860
|
-
|
|
11870
|
+
const safeX = isNaN(x) || !isFinite(x) ? 0 : x;
|
|
11871
|
+
const safeTaskX = isNaN(taskX) || !isFinite(taskX) ? 0 : taskX;
|
|
11872
|
+
const safeXStep = isNaN(xStep) || !isFinite(xStep) || xStep === 0 ? 1 : xStep;
|
|
11873
|
+
const safeTimeStep = isNaN(timeStep) || !isFinite(timeStep) ? 0 : timeStep;
|
|
11874
|
+
let newDate = new Date(
|
|
11875
|
+
(safeX - safeTaskX) / safeXStep * safeTimeStep + taskDate.getTime()
|
|
11876
|
+
);
|
|
11861
11877
|
newDate = new Date(
|
|
11862
11878
|
newDate.getTime() + (newDate.getTimezoneOffset() - taskDate.getTimezoneOffset()) * 6e4
|
|
11863
11879
|
);
|
|
@@ -13109,15 +13125,22 @@
|
|
|
13109
13125
|
x2: taskX2,
|
|
13110
13126
|
comparisonDates
|
|
13111
13127
|
} = getTaskCoordinates2(task);
|
|
13128
|
+
const safeContainerX = isNaN(containerX) || !isFinite(containerX) ? 0 : containerX;
|
|
13129
|
+
const safeContainerWidth = isNaN(containerWidth) || !isFinite(containerWidth) ? 0 : Math.max(containerWidth, 0);
|
|
13130
|
+
const safeWidth = isNaN(width) || !isFinite(width) ? 10 : Math.max(width, 1);
|
|
13131
|
+
const safeLevelY = isNaN(levelY) || !isFinite(levelY) ? 0 : levelY;
|
|
13132
|
+
const safeProgressWidth = isNaN(progressWidth) || !isFinite(progressWidth) ? 0 : Math.max(progressWidth, 0);
|
|
13133
|
+
const safeInnerX1 = isNaN(innerX1) || !isFinite(innerX1) ? 0 : innerX1;
|
|
13134
|
+
const safeInnerX2 = isNaN(innerX2) || !isFinite(innerX2) ? safeInnerX1 + safeWidth : innerX2;
|
|
13112
13135
|
tasksRes.push(
|
|
13113
13136
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13114
13137
|
"svg",
|
|
13115
13138
|
{
|
|
13116
13139
|
id: task.id,
|
|
13117
13140
|
className: `${styles$4.TaskItemWrapper} TaskItemWrapper`,
|
|
13118
|
-
x: Math.max(
|
|
13119
|
-
y:
|
|
13120
|
-
width: Math.max(
|
|
13141
|
+
x: Math.max(safeContainerX + (additionalLeftSpace || 0), 0),
|
|
13142
|
+
y: safeLevelY,
|
|
13143
|
+
width: Math.max(safeContainerWidth, 0),
|
|
13121
13144
|
height: fullRowHeight,
|
|
13122
13145
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13123
13146
|
TaskItem,
|
|
@@ -13125,14 +13148,14 @@
|
|
|
13125
13148
|
movingAction: taskBarMovingAction(task),
|
|
13126
13149
|
allowMoveTaskBar,
|
|
13127
13150
|
hasChildren: checkHasChildren(task, childTasksMap),
|
|
13128
|
-
progressWidth,
|
|
13129
|
-
progressX: rtl ?
|
|
13151
|
+
progressWidth: safeProgressWidth,
|
|
13152
|
+
progressX: rtl ? safeInnerX2 : safeInnerX1,
|
|
13130
13153
|
onSelectTaskOnMouseDown: selectTaskOnMouseDown,
|
|
13131
13154
|
task,
|
|
13132
13155
|
taskYOffset,
|
|
13133
|
-
width,
|
|
13134
|
-
x1:
|
|
13135
|
-
x2:
|
|
13156
|
+
width: safeWidth,
|
|
13157
|
+
x1: safeInnerX1,
|
|
13158
|
+
x2: safeInnerX2,
|
|
13136
13159
|
distances,
|
|
13137
13160
|
taskHeight,
|
|
13138
13161
|
taskHalfHeight,
|
|
@@ -13162,16 +13185,20 @@
|
|
|
13162
13185
|
)
|
|
13163
13186
|
);
|
|
13164
13187
|
if (task.comparisonDates && comparisonDates) {
|
|
13188
|
+
const safeComparisonX = isNaN(comparisonDates.x) || !isFinite(comparisonDates.x) ? 0 : comparisonDates.x;
|
|
13189
|
+
const safeComparisonY = isNaN(comparisonDates.y) || !isFinite(comparisonDates.y) ? safeLevelY : comparisonDates.y;
|
|
13190
|
+
const safeComparisonWidth = isNaN(comparisonDates.width) || !isFinite(comparisonDates.width) ? 10 : Math.max(comparisonDates.width, 1);
|
|
13191
|
+
const safeComparisonHeight = isNaN(comparisonDates.height) || !isFinite(comparisonDates.height) ? 4 : Math.max(comparisonDates.height, 1);
|
|
13165
13192
|
tasksRes.push(
|
|
13166
13193
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13167
13194
|
"svg",
|
|
13168
13195
|
{
|
|
13169
13196
|
id: task.id + "_comparison",
|
|
13170
13197
|
className: "TaskItemWrapperComparison",
|
|
13171
|
-
x: Math.max(
|
|
13172
|
-
y:
|
|
13173
|
-
width:
|
|
13174
|
-
height:
|
|
13198
|
+
x: Math.max(safeComparisonX + (additionalLeftSpace || 0), 0),
|
|
13199
|
+
y: safeComparisonY,
|
|
13200
|
+
width: safeComparisonWidth,
|
|
13201
|
+
height: safeComparisonHeight * 2,
|
|
13175
13202
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13176
13203
|
BarComparison,
|
|
13177
13204
|
{
|
|
@@ -13180,8 +13207,8 @@
|
|
|
13180
13207
|
isWarning: !!task.comparisonDates.end && task.comparisonDates.end.getTime() >= task.end.getTime(),
|
|
13181
13208
|
isCritical: task.comparisonDates.start.getTime() > task.start.getTime(),
|
|
13182
13209
|
barCornerRadius: distances.barCornerRadius,
|
|
13183
|
-
height:
|
|
13184
|
-
width:
|
|
13210
|
+
height: safeComparisonHeight,
|
|
13211
|
+
width: safeComparisonWidth,
|
|
13185
13212
|
borderHeight: distances.barComparisonTaskBorderHeight,
|
|
13186
13213
|
yOffset: distances.barComparisonTaskYOffset,
|
|
13187
13214
|
task,
|
|
@@ -13224,15 +13251,24 @@
|
|
|
13224
13251
|
addedDependenciesAtTask[source.id] = true;
|
|
13225
13252
|
const isCritical2 = criticalPathForTask ? criticalPathForTask.has(source.id) : false;
|
|
13226
13253
|
const { x1: fromX1, x2: fromX2 } = getTaskCoordinates2(source);
|
|
13227
|
-
const
|
|
13228
|
-
const
|
|
13254
|
+
const safeFromX1 = isNaN(fromX1) || !isFinite(fromX1) ? 0 : fromX1;
|
|
13255
|
+
const safeFromX2 = isNaN(fromX2) || !isFinite(fromX2) ? safeFromX1 + 10 : fromX2;
|
|
13256
|
+
const safeTaskX1 = isNaN(taskX1) || !isFinite(taskX1) ? 0 : taskX1;
|
|
13257
|
+
const safeTaskX2 = isNaN(taskX2) || !isFinite(taskX2) ? safeTaskX1 + 10 : taskX2;
|
|
13258
|
+
const containerX2 = Math.min(safeFromX1, safeTaskX1) - DELTA_RELATION_WIDTH;
|
|
13259
|
+
const containerWidth2 = Math.max(safeFromX2, safeTaskX2) - containerX2 + DELTA_RELATION_WIDTH;
|
|
13260
|
+
const safeArrowContainerX = isNaN(containerX2) || !isFinite(containerX2) ? 0 : containerX2;
|
|
13261
|
+
const safeArrowContainerWidth = isNaN(containerWidth2) || !isFinite(containerWidth2) ? 100 : Math.max(containerWidth2, 0);
|
|
13229
13262
|
arrowsRes.push(
|
|
13230
13263
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13231
13264
|
"svg",
|
|
13232
13265
|
{
|
|
13233
|
-
x: Math.max(
|
|
13266
|
+
x: Math.max(
|
|
13267
|
+
safeArrowContainerX + (additionalLeftSpace || 0),
|
|
13268
|
+
0
|
|
13269
|
+
),
|
|
13234
13270
|
y: containerY,
|
|
13235
|
-
width:
|
|
13271
|
+
width: safeArrowContainerWidth,
|
|
13236
13272
|
height: containerHeight,
|
|
13237
13273
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13238
13274
|
Arrow,
|
|
@@ -13240,13 +13276,13 @@
|
|
|
13240
13276
|
distances,
|
|
13241
13277
|
taskFrom: source,
|
|
13242
13278
|
targetFrom: sourceTarget,
|
|
13243
|
-
fromX1:
|
|
13244
|
-
fromX2:
|
|
13279
|
+
fromX1: safeFromX1 - safeArrowContainerX,
|
|
13280
|
+
fromX2: safeFromX2 - safeArrowContainerX,
|
|
13245
13281
|
fromY: innerFromY,
|
|
13246
13282
|
taskTo: task,
|
|
13247
13283
|
targetTo: ownTarget,
|
|
13248
|
-
toX1:
|
|
13249
|
-
toX2:
|
|
13284
|
+
toX1: safeTaskX1 - safeArrowContainerX,
|
|
13285
|
+
toX2: safeTaskX2 - safeArrowContainerX,
|
|
13250
13286
|
toY: innerToY,
|
|
13251
13287
|
fullRowHeight,
|
|
13252
13288
|
taskHeight,
|
|
@@ -13289,15 +13325,24 @@
|
|
|
13289
13325
|
const criticalPathForTask = criticalPathOnLevel ? criticalPathOnLevel.dependencies.get(dependent.id) : void 0;
|
|
13290
13326
|
const isCritical2 = criticalPathForTask ? criticalPathForTask.has(task.id) : false;
|
|
13291
13327
|
const { x1: toX1, x2: toX2 } = getTaskCoordinates2(dependent);
|
|
13292
|
-
const
|
|
13293
|
-
const
|
|
13328
|
+
const safeToX1 = isNaN(toX1) || !isFinite(toX1) ? 0 : toX1;
|
|
13329
|
+
const safeToX2 = isNaN(toX2) || !isFinite(toX2) ? safeToX1 + 10 : toX2;
|
|
13330
|
+
const safeTaskX1 = isNaN(taskX1) || !isFinite(taskX1) ? 0 : taskX1;
|
|
13331
|
+
const safeTaskX2 = isNaN(taskX2) || !isFinite(taskX2) ? safeTaskX1 + 10 : taskX2;
|
|
13332
|
+
const containerX2 = Math.min(safeToX1, safeTaskX1) - DELTA_RELATION_WIDTH;
|
|
13333
|
+
const containerWidth2 = Math.max(safeToX2, safeTaskX2) - containerX2 + DELTA_RELATION_WIDTH;
|
|
13334
|
+
const safeArrowContainerX = isNaN(containerX2) || !isFinite(containerX2) ? 0 : containerX2;
|
|
13335
|
+
const safeArrowContainerWidth = isNaN(containerWidth2) || !isFinite(containerWidth2) ? 100 : Math.max(containerWidth2, 0);
|
|
13294
13336
|
arrowsRes.push(
|
|
13295
13337
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
13296
13338
|
"svg",
|
|
13297
13339
|
{
|
|
13298
|
-
x: Math.max(
|
|
13340
|
+
x: Math.max(
|
|
13341
|
+
safeArrowContainerX + (additionalLeftSpace || 0),
|
|
13342
|
+
0
|
|
13343
|
+
),
|
|
13299
13344
|
y: containerY,
|
|
13300
|
-
width:
|
|
13345
|
+
width: safeArrowContainerWidth,
|
|
13301
13346
|
height: containerHeight,
|
|
13302
13347
|
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
13303
13348
|
Arrow,
|
|
@@ -13305,13 +13350,13 @@
|
|
|
13305
13350
|
distances,
|
|
13306
13351
|
taskFrom: task,
|
|
13307
13352
|
targetFrom: ownTarget,
|
|
13308
|
-
fromX1:
|
|
13309
|
-
fromX2:
|
|
13353
|
+
fromX1: safeTaskX1 - safeArrowContainerX,
|
|
13354
|
+
fromX2: safeTaskX2 - safeArrowContainerX,
|
|
13310
13355
|
fromY: innerFromY,
|
|
13311
13356
|
taskTo: dependent,
|
|
13312
13357
|
targetTo: dependentTarget,
|
|
13313
|
-
toX1:
|
|
13314
|
-
toX2:
|
|
13358
|
+
toX1: safeToX1 - safeArrowContainerX,
|
|
13359
|
+
toX2: safeToX2 - safeArrowContainerX,
|
|
13315
13360
|
toY: innerToY,
|
|
13316
13361
|
fullRowHeight,
|
|
13317
13362
|
taskHeight,
|
|
@@ -13789,21 +13834,26 @@
|
|
|
13789
13834
|
if (typeof rowIndex !== "number") {
|
|
13790
13835
|
throw new Error(`Row index for task ${id} is not found`);
|
|
13791
13836
|
}
|
|
13792
|
-
|
|
13793
|
-
|
|
13837
|
+
let x1 = rtl ? svgWidth - taskXCoordinate(task.end, startDate, viewMode, columnWidth) : taskXCoordinate(task.start, startDate, viewMode, columnWidth);
|
|
13838
|
+
let x2 = rtl ? svgWidth - taskXCoordinate(task.start, startDate, viewMode, columnWidth) : taskXCoordinate(task.end, startDate, viewMode, columnWidth);
|
|
13839
|
+
x1 = isNaN(x1) || !isFinite(x1) ? 0 : x1;
|
|
13840
|
+
x2 = isNaN(x2) || !isFinite(x2) ? Math.max(x1, 10) : x2;
|
|
13794
13841
|
const levelY = rowIndex * fullRowHeight + rowHeight * (comparisonLevel - 1);
|
|
13795
13842
|
const y = levelY + taskYOffset;
|
|
13796
13843
|
const [progressWidth, progressX] = type === "milestone" ? [0, x1] : progressWithByParams(x1, x2, progress, rtl);
|
|
13797
13844
|
const taskX1 = type === "milestone" ? x1 - taskHeight * 0.5 : x1;
|
|
13798
13845
|
const taskX2 = type === "milestone" ? x2 + taskHeight * 0.5 : x2;
|
|
13799
|
-
|
|
13800
|
-
|
|
13801
|
-
|
|
13846
|
+
let taskWidth = type === "milestone" ? taskHeight : Math.max(taskX2 - taskX1, 10);
|
|
13847
|
+
taskWidth = isNaN(taskWidth) || !isFinite(taskWidth) ? 10 : Math.max(taskWidth, 1);
|
|
13848
|
+
let containerX = taskX1 - columnWidth;
|
|
13849
|
+
containerX = isNaN(containerX) || !isFinite(containerX) ? 0 : containerX;
|
|
13850
|
+
let containerWidth = svgWidth - containerX;
|
|
13851
|
+
containerWidth = isNaN(containerWidth) || !isFinite(containerWidth) ? svgWidth : Math.max(containerWidth, 0);
|
|
13802
13852
|
const innerX1 = columnWidth;
|
|
13803
13853
|
const innerX2 = columnWidth + taskWidth;
|
|
13804
13854
|
let comparisonDates;
|
|
13805
13855
|
if (task.comparisonDates) {
|
|
13806
|
-
|
|
13856
|
+
let cx1 = rtl ? svgWidth - taskComparisonXCoordinate(
|
|
13807
13857
|
task.comparisonDates.end || task.end,
|
|
13808
13858
|
startDate,
|
|
13809
13859
|
viewMode,
|
|
@@ -13814,7 +13864,7 @@
|
|
|
13814
13864
|
viewMode,
|
|
13815
13865
|
columnWidth
|
|
13816
13866
|
);
|
|
13817
|
-
|
|
13867
|
+
let cx2 = rtl ? svgWidth - taskComparisonXCoordinate(
|
|
13818
13868
|
task.comparisonDates.start,
|
|
13819
13869
|
startDate,
|
|
13820
13870
|
viewMode,
|
|
@@ -13825,10 +13875,13 @@
|
|
|
13825
13875
|
viewMode,
|
|
13826
13876
|
columnWidth
|
|
13827
13877
|
);
|
|
13878
|
+
cx1 = isNaN(cx1) || !isFinite(cx1) ? x1 : cx1;
|
|
13879
|
+
cx2 = isNaN(cx2) || !isFinite(cx2) ? x2 : cx2;
|
|
13828
13880
|
comparisonDates = {
|
|
13829
13881
|
x: cx1,
|
|
13830
13882
|
y: y + taskHeight,
|
|
13831
|
-
width: Math.max(cx2 - cx1,
|
|
13883
|
+
width: Math.max(cx2 - cx1, 1),
|
|
13884
|
+
// Ensure minimum width of 1px for visibility
|
|
13832
13885
|
height: barComparisonTaskHeight
|
|
13833
13886
|
};
|
|
13834
13887
|
}
|
|
@@ -17503,308 +17556,6 @@
|
|
|
17503
17556
|
scrollToRightStep
|
|
17504
17557
|
];
|
|
17505
17558
|
};
|
|
17506
|
-
const usePerformanceMonitor = (enabled = true) => {
|
|
17507
|
-
const metricsRef = React.useRef([]);
|
|
17508
|
-
const benchmarksRef = React.useRef(/* @__PURE__ */ new Map());
|
|
17509
|
-
const frameTimesRef = React.useRef([]);
|
|
17510
|
-
const lastFrameTimeRef = React.useRef(performance.now());
|
|
17511
|
-
const updateFPS = React.useCallback(() => {
|
|
17512
|
-
if (!enabled)
|
|
17513
|
-
return;
|
|
17514
|
-
const now = performance.now();
|
|
17515
|
-
const deltaTime = now - lastFrameTimeRef.current;
|
|
17516
|
-
lastFrameTimeRef.current = now;
|
|
17517
|
-
frameTimesRef.current.push(deltaTime);
|
|
17518
|
-
if (frameTimesRef.current.length > 60) {
|
|
17519
|
-
frameTimesRef.current.shift();
|
|
17520
|
-
}
|
|
17521
|
-
}, [enabled]);
|
|
17522
|
-
const getFPS = React.useCallback(() => {
|
|
17523
|
-
if (frameTimesRef.current.length === 0)
|
|
17524
|
-
return 0;
|
|
17525
|
-
const avgFrameTime = frameTimesRef.current.reduce((sum, time) => sum + time, 0) / frameTimesRef.current.length;
|
|
17526
|
-
return Math.round(1e3 / avgFrameTime);
|
|
17527
|
-
}, []);
|
|
17528
|
-
const startMeasurement = React.useCallback(
|
|
17529
|
-
(name, metadata) => {
|
|
17530
|
-
if (!enabled)
|
|
17531
|
-
return;
|
|
17532
|
-
performance.mark(`${name}-start`);
|
|
17533
|
-
benchmarksRef.current.set(name, {
|
|
17534
|
-
name,
|
|
17535
|
-
startTime: performance.now(),
|
|
17536
|
-
metadata
|
|
17537
|
-
});
|
|
17538
|
-
},
|
|
17539
|
-
[enabled]
|
|
17540
|
-
);
|
|
17541
|
-
const endMeasurement = React.useCallback(
|
|
17542
|
-
(name) => {
|
|
17543
|
-
if (!enabled)
|
|
17544
|
-
return 0;
|
|
17545
|
-
const benchmark = benchmarksRef.current.get(name);
|
|
17546
|
-
if (!benchmark) {
|
|
17547
|
-
console.warn(`No benchmark found for ${name}`);
|
|
17548
|
-
return 0;
|
|
17549
|
-
}
|
|
17550
|
-
const endTime = performance.now();
|
|
17551
|
-
const duration = endTime - benchmark.startTime;
|
|
17552
|
-
performance.mark(`${name}-end`);
|
|
17553
|
-
performance.measure(name, `${name}-start`, `${name}-end`);
|
|
17554
|
-
benchmark.endTime = endTime;
|
|
17555
|
-
benchmark.duration = duration;
|
|
17556
|
-
return duration;
|
|
17557
|
-
},
|
|
17558
|
-
[enabled]
|
|
17559
|
-
);
|
|
17560
|
-
const measureFunction = React.useCallback(
|
|
17561
|
-
(name, fn, metadata) => {
|
|
17562
|
-
return (...args) => {
|
|
17563
|
-
if (!enabled)
|
|
17564
|
-
return fn(...args);
|
|
17565
|
-
startMeasurement(name, metadata);
|
|
17566
|
-
try {
|
|
17567
|
-
const result = fn(...args);
|
|
17568
|
-
return result;
|
|
17569
|
-
} finally {
|
|
17570
|
-
endMeasurement(name);
|
|
17571
|
-
}
|
|
17572
|
-
};
|
|
17573
|
-
},
|
|
17574
|
-
[enabled, startMeasurement, endMeasurement]
|
|
17575
|
-
);
|
|
17576
|
-
const measureAsyncFunction = React.useCallback(
|
|
17577
|
-
(name, fn, metadata) => {
|
|
17578
|
-
return async (...args) => {
|
|
17579
|
-
if (!enabled)
|
|
17580
|
-
return fn(...args);
|
|
17581
|
-
startMeasurement(name, metadata);
|
|
17582
|
-
try {
|
|
17583
|
-
const result = await fn(...args);
|
|
17584
|
-
return result;
|
|
17585
|
-
} finally {
|
|
17586
|
-
endMeasurement(name);
|
|
17587
|
-
}
|
|
17588
|
-
};
|
|
17589
|
-
},
|
|
17590
|
-
[enabled, startMeasurement, endMeasurement]
|
|
17591
|
-
);
|
|
17592
|
-
const getPerformanceReport = React.useCallback(() => {
|
|
17593
|
-
const entries = performance.getEntriesByType(
|
|
17594
|
-
"measure"
|
|
17595
|
-
);
|
|
17596
|
-
const report = {};
|
|
17597
|
-
entries.forEach((entry) => {
|
|
17598
|
-
if (!report[entry.name]) {
|
|
17599
|
-
report[entry.name] = {
|
|
17600
|
-
count: 0,
|
|
17601
|
-
totalTime: 0,
|
|
17602
|
-
avgTime: 0,
|
|
17603
|
-
maxTime: 0,
|
|
17604
|
-
minTime: Infinity
|
|
17605
|
-
};
|
|
17606
|
-
}
|
|
17607
|
-
const stat = report[entry.name];
|
|
17608
|
-
stat.count++;
|
|
17609
|
-
stat.totalTime += entry.duration;
|
|
17610
|
-
stat.maxTime = Math.max(stat.maxTime, entry.duration);
|
|
17611
|
-
stat.minTime = Math.min(stat.minTime, entry.duration);
|
|
17612
|
-
stat.avgTime = stat.totalTime / stat.count;
|
|
17613
|
-
});
|
|
17614
|
-
return {
|
|
17615
|
-
measurements: report,
|
|
17616
|
-
fps: getFPS(),
|
|
17617
|
-
currentMetrics: metricsRef.current[metricsRef.current.length - 1],
|
|
17618
|
-
allMetrics: [...metricsRef.current]
|
|
17619
|
-
};
|
|
17620
|
-
}, [getFPS]);
|
|
17621
|
-
const addMetrics = React.useCallback(
|
|
17622
|
-
(metrics) => {
|
|
17623
|
-
if (!enabled)
|
|
17624
|
-
return;
|
|
17625
|
-
const fullMetrics = {
|
|
17626
|
-
...metrics,
|
|
17627
|
-
timestamp: Date.now()
|
|
17628
|
-
};
|
|
17629
|
-
metricsRef.current.push(fullMetrics);
|
|
17630
|
-
if (metricsRef.current.length > 100) {
|
|
17631
|
-
metricsRef.current.shift();
|
|
17632
|
-
}
|
|
17633
|
-
},
|
|
17634
|
-
[enabled]
|
|
17635
|
-
);
|
|
17636
|
-
const clearMeasurements = React.useCallback(() => {
|
|
17637
|
-
performance.clearMarks();
|
|
17638
|
-
performance.clearMeasures();
|
|
17639
|
-
benchmarksRef.current.clear();
|
|
17640
|
-
metricsRef.current.length = 0;
|
|
17641
|
-
frameTimesRef.current.length = 0;
|
|
17642
|
-
}, []);
|
|
17643
|
-
const getMemoryUsage = React.useCallback(() => {
|
|
17644
|
-
if ("memory" in performance) {
|
|
17645
|
-
const memory = performance.memory;
|
|
17646
|
-
return memory ? memory.usedJSHeapSize : 0;
|
|
17647
|
-
}
|
|
17648
|
-
return 0;
|
|
17649
|
-
}, []);
|
|
17650
|
-
return {
|
|
17651
|
-
startMeasurement,
|
|
17652
|
-
endMeasurement,
|
|
17653
|
-
measureFunction,
|
|
17654
|
-
measureAsyncFunction,
|
|
17655
|
-
getPerformanceReport,
|
|
17656
|
-
addMetrics,
|
|
17657
|
-
clearMeasurements,
|
|
17658
|
-
updateFPS,
|
|
17659
|
-
getFPS,
|
|
17660
|
-
getMemoryUsage,
|
|
17661
|
-
enabled
|
|
17662
|
-
};
|
|
17663
|
-
};
|
|
17664
|
-
const useAdaptivePerformance = (thresholds) => {
|
|
17665
|
-
const { getFPS, getPerformanceReport } = usePerformanceMonitor();
|
|
17666
|
-
const performanceLevelRef = React.useRef("high");
|
|
17667
|
-
const updatePerformanceLevel = React.useCallback(() => {
|
|
17668
|
-
var _a;
|
|
17669
|
-
const fps = getFPS();
|
|
17670
|
-
const report = getPerformanceReport();
|
|
17671
|
-
const renderTime = ((_a = report.measurements["render"]) == null ? void 0 : _a.avgTime) || 0;
|
|
17672
|
-
if (fps < thresholds.fpsThreshold * 0.5 || renderTime > thresholds.renderTimeThreshold * 2) {
|
|
17673
|
-
performanceLevelRef.current = "low";
|
|
17674
|
-
} else if (fps < thresholds.fpsThreshold || renderTime > thresholds.renderTimeThreshold) {
|
|
17675
|
-
performanceLevelRef.current = "medium";
|
|
17676
|
-
} else {
|
|
17677
|
-
performanceLevelRef.current = "high";
|
|
17678
|
-
}
|
|
17679
|
-
return performanceLevelRef.current;
|
|
17680
|
-
}, [getFPS, getPerformanceReport, thresholds]);
|
|
17681
|
-
const getQualitySettings = React.useCallback(() => {
|
|
17682
|
-
const level = performanceLevelRef.current;
|
|
17683
|
-
switch (level) {
|
|
17684
|
-
case "low":
|
|
17685
|
-
return {
|
|
17686
|
-
enableAnimations: false,
|
|
17687
|
-
renderQuality: "low",
|
|
17688
|
-
maxVisibleTasks: 100,
|
|
17689
|
-
updateFrequency: 500
|
|
17690
|
-
// ms
|
|
17691
|
-
};
|
|
17692
|
-
case "medium":
|
|
17693
|
-
return {
|
|
17694
|
-
enableAnimations: true,
|
|
17695
|
-
renderQuality: "medium",
|
|
17696
|
-
maxVisibleTasks: 500,
|
|
17697
|
-
updateFrequency: 100
|
|
17698
|
-
};
|
|
17699
|
-
case "high":
|
|
17700
|
-
default:
|
|
17701
|
-
return {
|
|
17702
|
-
enableAnimations: true,
|
|
17703
|
-
renderQuality: "high",
|
|
17704
|
-
maxVisibleTasks: 1e3,
|
|
17705
|
-
updateFrequency: 16
|
|
17706
|
-
// 60fps
|
|
17707
|
-
};
|
|
17708
|
-
}
|
|
17709
|
-
}, []);
|
|
17710
|
-
return {
|
|
17711
|
-
performanceLevel: performanceLevelRef.current,
|
|
17712
|
-
updatePerformanceLevel,
|
|
17713
|
-
getQualitySettings
|
|
17714
|
-
};
|
|
17715
|
-
};
|
|
17716
|
-
const useIncrementalCoordinates = (visibleTasks, visibleTasksMirror, taskToRowIndexMap, startDate, viewMode, rtl, fullRowHeight, taskHeight, taskYOffset, distances, svgWidth, renderedRowIndexes, renderedColumnIndexes) => {
|
|
17717
|
-
const cacheRef = React.useRef({
|
|
17718
|
-
coordinates: /* @__PURE__ */ new Map(),
|
|
17719
|
-
lastUpdateParams: null
|
|
17720
|
-
});
|
|
17721
|
-
return React.useMemo(() => {
|
|
17722
|
-
const cache = cacheRef.current;
|
|
17723
|
-
const currentParams = {
|
|
17724
|
-
startDate,
|
|
17725
|
-
viewMode,
|
|
17726
|
-
rtl,
|
|
17727
|
-
fullRowHeight,
|
|
17728
|
-
taskHeight,
|
|
17729
|
-
taskYOffset,
|
|
17730
|
-
svgWidth,
|
|
17731
|
-
distances
|
|
17732
|
-
};
|
|
17733
|
-
const needsFullRecalc = !cache.lastUpdateParams || cache.lastUpdateParams.startDate.getTime() !== startDate.getTime() || cache.lastUpdateParams.viewMode !== viewMode || cache.lastUpdateParams.rtl !== rtl || cache.lastUpdateParams.fullRowHeight !== fullRowHeight || cache.lastUpdateParams.taskHeight !== taskHeight || cache.lastUpdateParams.taskYOffset !== taskYOffset || cache.lastUpdateParams.svgWidth !== svgWidth || JSON.stringify(cache.lastUpdateParams.distances) !== JSON.stringify(distances);
|
|
17734
|
-
if (needsFullRecalc) {
|
|
17735
|
-
cache.coordinates.clear();
|
|
17736
|
-
}
|
|
17737
|
-
const tasksToCalculate = /* @__PURE__ */ new Set();
|
|
17738
|
-
if (renderedRowIndexes && renderedColumnIndexes) {
|
|
17739
|
-
const [startRow, endRow] = renderedRowIndexes;
|
|
17740
|
-
const rowBuffer = Math.max(5, Math.ceil((endRow - startRow) * 0.5));
|
|
17741
|
-
const bufferedStartRow = Math.max(0, startRow - rowBuffer);
|
|
17742
|
-
const bufferedEndRow = endRow + rowBuffer;
|
|
17743
|
-
visibleTasks.forEach((task, index2) => {
|
|
17744
|
-
if (task.type === "empty" || !visibleTasksMirror[task.id])
|
|
17745
|
-
return;
|
|
17746
|
-
if (index2 >= bufferedStartRow && index2 <= bufferedEndRow) {
|
|
17747
|
-
tasksToCalculate.add(task.id);
|
|
17748
|
-
}
|
|
17749
|
-
});
|
|
17750
|
-
} else {
|
|
17751
|
-
visibleTasks.forEach((task) => {
|
|
17752
|
-
if (task.type !== "empty" && visibleTasksMirror[task.id]) {
|
|
17753
|
-
tasksToCalculate.add(task.id);
|
|
17754
|
-
}
|
|
17755
|
-
});
|
|
17756
|
-
}
|
|
17757
|
-
if (!needsFullRecalc) {
|
|
17758
|
-
for (const [taskId] of cache.coordinates) {
|
|
17759
|
-
if (!tasksToCalculate.has(taskId)) {
|
|
17760
|
-
cache.coordinates.delete(taskId);
|
|
17761
|
-
}
|
|
17762
|
-
}
|
|
17763
|
-
}
|
|
17764
|
-
const res = /* @__PURE__ */ new Map();
|
|
17765
|
-
visibleTasks.forEach((task) => {
|
|
17766
|
-
if (task.type === "empty" || !tasksToCalculate.has(task.id))
|
|
17767
|
-
return;
|
|
17768
|
-
const { id, comparisonLevel = 1 } = task;
|
|
17769
|
-
const cacheKey = `${id}_${comparisonLevel}`;
|
|
17770
|
-
let taskCoordinates = cache.coordinates.get(cacheKey);
|
|
17771
|
-
if (!taskCoordinates || needsFullRecalc) {
|
|
17772
|
-
taskCoordinates = countTaskCoordinates(
|
|
17773
|
-
task,
|
|
17774
|
-
taskToRowIndexMap,
|
|
17775
|
-
startDate,
|
|
17776
|
-
viewMode,
|
|
17777
|
-
rtl,
|
|
17778
|
-
fullRowHeight,
|
|
17779
|
-
taskHeight,
|
|
17780
|
-
taskYOffset,
|
|
17781
|
-
distances,
|
|
17782
|
-
svgWidth
|
|
17783
|
-
);
|
|
17784
|
-
cache.coordinates.set(cacheKey, taskCoordinates);
|
|
17785
|
-
}
|
|
17786
|
-
const resByLevel = res.get(comparisonLevel) || /* @__PURE__ */ new Map();
|
|
17787
|
-
resByLevel.set(id, taskCoordinates);
|
|
17788
|
-
res.set(comparisonLevel, resByLevel);
|
|
17789
|
-
});
|
|
17790
|
-
cache.lastUpdateParams = currentParams;
|
|
17791
|
-
return res;
|
|
17792
|
-
}, [
|
|
17793
|
-
visibleTasks,
|
|
17794
|
-
visibleTasksMirror,
|
|
17795
|
-
taskToRowIndexMap,
|
|
17796
|
-
startDate,
|
|
17797
|
-
viewMode,
|
|
17798
|
-
rtl,
|
|
17799
|
-
fullRowHeight,
|
|
17800
|
-
taskHeight,
|
|
17801
|
-
taskYOffset,
|
|
17802
|
-
distances,
|
|
17803
|
-
svgWidth,
|
|
17804
|
-
renderedRowIndexes,
|
|
17805
|
-
renderedColumnIndexes
|
|
17806
|
-
]);
|
|
17807
|
-
};
|
|
17808
17559
|
const fillMinAndMaxChildsMap = (resOnLevel, task, childTasksOnLevel) => {
|
|
17809
17560
|
const childs = childTasksOnLevel.get(task.id);
|
|
17810
17561
|
if (!childs || childs.length === 0) {
|
|
@@ -19424,11 +19175,6 @@
|
|
|
19424
19175
|
() => getChildsAndRoots(sortedTasks, null),
|
|
19425
19176
|
[sortedTasks]
|
|
19426
19177
|
);
|
|
19427
|
-
const adaptiveSettings = useAdaptivePerformance({
|
|
19428
|
-
fpsThreshold: 30,
|
|
19429
|
-
renderTimeThreshold: 16
|
|
19430
|
-
// 60fps = 16ms per frame
|
|
19431
|
-
});
|
|
19432
19178
|
const minAndMaxChildsMap = React.useMemo(
|
|
19433
19179
|
() => getMinAndMaxChildsMap(rootTasksMap, childTasksMap),
|
|
19434
19180
|
[rootTasksMap, childTasksMap]
|
|
@@ -19602,7 +19348,7 @@
|
|
|
19602
19348
|
svgWidth
|
|
19603
19349
|
]
|
|
19604
19350
|
);
|
|
19605
|
-
const
|
|
19351
|
+
const mapTaskToCoordinates = React.useMemo(
|
|
19606
19352
|
() => getMapTaskToCoordinates(
|
|
19607
19353
|
sortedTasks,
|
|
19608
19354
|
visibleTasksMirror,
|
|
@@ -19630,24 +19376,6 @@
|
|
|
19630
19376
|
visibleTasksMirror
|
|
19631
19377
|
]
|
|
19632
19378
|
);
|
|
19633
|
-
const optimizedMapTaskToCoordinates = useIncrementalCoordinates(
|
|
19634
|
-
visibleTasks,
|
|
19635
|
-
visibleTasksMirror,
|
|
19636
|
-
taskToRowIndexMap,
|
|
19637
|
-
startDate,
|
|
19638
|
-
viewMode,
|
|
19639
|
-
rtl,
|
|
19640
|
-
fullRowHeight,
|
|
19641
|
-
taskHeight,
|
|
19642
|
-
taskYOffset,
|
|
19643
|
-
distances,
|
|
19644
|
-
svgWidth,
|
|
19645
|
-
null,
|
|
19646
|
-
// renderedRowIndexes - can be integrated later with virtualization
|
|
19647
|
-
null
|
|
19648
|
-
// renderedColumnIndexes - can be integrated later with virtualization
|
|
19649
|
-
);
|
|
19650
|
-
const mapTaskToCoordinates = adaptiveSettings.performanceLevel === "high" ? optimizedMapTaskToCoordinates : originalMapTaskToCoordinates;
|
|
19651
19379
|
const scrollToTask = React.useCallback(
|
|
19652
19380
|
(task) => {
|
|
19653
19381
|
const { x1 } = getTaskCoordinates(task, mapTaskToCoordinates);
|
package/package.json
CHANGED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import { Distances, MapTaskToCoordinates, TaskCoordinates, RenderTask, TaskToRowIndexMap, ViewMode } from "../types";
|
|
2
|
-
import type { OptimizedListParams } from "./use-optimized-list";
|
|
3
|
-
/**
|
|
4
|
-
* Optimized hook for calculating task coordinates incrementally
|
|
5
|
-
* Only recalculates coordinates for visible tasks and caches results
|
|
6
|
-
*/
|
|
7
|
-
export declare const useIncrementalCoordinates: (visibleTasks: readonly RenderTask[], visibleTasksMirror: Readonly<Record<string, true>>, taskToRowIndexMap: TaskToRowIndexMap, startDate: Date, viewMode: ViewMode, rtl: boolean, fullRowHeight: number, taskHeight: number, taskYOffset: number, distances: Distances, svgWidth: number, renderedRowIndexes: OptimizedListParams | null, renderedColumnIndexes: OptimizedListParams | null) => MapTaskToCoordinates;
|
|
8
|
-
/**
|
|
9
|
-
* Hook for getting coordinates of tasks in a specific range only
|
|
10
|
-
* Useful for virtual scrolling scenarios
|
|
11
|
-
*/
|
|
12
|
-
export declare const useRangedCoordinates: (tasks: readonly RenderTask[], taskToRowIndexMap: TaskToRowIndexMap, startDate: Date, viewMode: ViewMode, rtl: boolean, fullRowHeight: number, taskHeight: number, taskYOffset: number, distances: Distances, svgWidth: number, startIndex: number, endIndex: number, comparisonLevel?: number) => Map<string, TaskCoordinates>;
|
|
13
|
-
/**
|
|
14
|
-
* Hook for smart coordinate invalidation
|
|
15
|
-
* Tracks which tasks need coordinate recalculation based on their dependencies
|
|
16
|
-
*/
|
|
17
|
-
export declare const useCoordinateInvalidation: (tasks: readonly RenderTask[], changedTaskIds: Set<string>) => Set<string>;
|