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
|
@@ -11818,29 +11818,45 @@ const taskXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
|
|
|
11818
11818
|
const currentDate = getDateByOffset(startDate, index2, viewMode);
|
|
11819
11819
|
const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
|
|
11820
11820
|
const remainderMillis = xDate.getTime() - currentDate.getTime();
|
|
11821
|
-
const
|
|
11822
|
-
|
|
11821
|
+
const intervalDuration = nextDate.getTime() - currentDate.getTime();
|
|
11822
|
+
const percentOfInterval = intervalDuration === 0 ? 0 : remainderMillis / intervalDuration;
|
|
11823
|
+
const result = index2 * columnWidth + percentOfInterval * columnWidth;
|
|
11824
|
+
return isNaN(result) || !isFinite(result) ? 0 : result;
|
|
11823
11825
|
};
|
|
11824
11826
|
const taskComparisonXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
|
|
11825
11827
|
const index2 = getDatesDiff(xDate, startDate, viewMode);
|
|
11826
11828
|
const currentDate = getDateByOffset(startDate, index2, viewMode);
|
|
11827
11829
|
const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
|
|
11828
11830
|
const remainderMillis = xDate.getTime() - currentDate.getTime();
|
|
11829
|
-
const
|
|
11830
|
-
|
|
11831
|
+
const intervalDuration = nextDate.getTime() - currentDate.getTime();
|
|
11832
|
+
const percentOfInterval = intervalDuration === 0 ? 0 : remainderMillis / intervalDuration;
|
|
11833
|
+
const result = index2 * columnWidth + percentOfInterval * columnWidth;
|
|
11834
|
+
return isNaN(result) || !isFinite(result) ? 0 : result;
|
|
11831
11835
|
};
|
|
11832
11836
|
const progressWithByParams = (taskX1, taskX2, progress, rtl) => {
|
|
11833
|
-
const
|
|
11837
|
+
const safeTaskX1 = isNaN(taskX1) || !isFinite(taskX1) ? 0 : taskX1;
|
|
11838
|
+
const safeTaskX2 = isNaN(taskX2) || !isFinite(taskX2) ? 0 : taskX2;
|
|
11839
|
+
const safeProgress = isNaN(progress) || !isFinite(progress) ? 0 : progress;
|
|
11840
|
+
const progressWidth = Math.max(
|
|
11841
|
+
(safeTaskX2 - safeTaskX1) * safeProgress * 0.01,
|
|
11842
|
+
0
|
|
11843
|
+
);
|
|
11834
11844
|
let progressX;
|
|
11835
11845
|
if (rtl) {
|
|
11836
|
-
progressX =
|
|
11846
|
+
progressX = safeTaskX2 - progressWidth;
|
|
11837
11847
|
} else {
|
|
11838
|
-
progressX =
|
|
11848
|
+
progressX = safeTaskX1;
|
|
11839
11849
|
}
|
|
11840
11850
|
return [progressWidth, progressX];
|
|
11841
11851
|
};
|
|
11842
11852
|
const dateByX = (x, taskX, taskDate, xStep, timeStep) => {
|
|
11843
|
-
|
|
11853
|
+
const safeX = isNaN(x) || !isFinite(x) ? 0 : x;
|
|
11854
|
+
const safeTaskX = isNaN(taskX) || !isFinite(taskX) ? 0 : taskX;
|
|
11855
|
+
const safeXStep = isNaN(xStep) || !isFinite(xStep) || xStep === 0 ? 1 : xStep;
|
|
11856
|
+
const safeTimeStep = isNaN(timeStep) || !isFinite(timeStep) ? 0 : timeStep;
|
|
11857
|
+
let newDate = new Date(
|
|
11858
|
+
(safeX - safeTaskX) / safeXStep * safeTimeStep + taskDate.getTime()
|
|
11859
|
+
);
|
|
11844
11860
|
newDate = new Date(
|
|
11845
11861
|
newDate.getTime() + (newDate.getTimezoneOffset() - taskDate.getTimezoneOffset()) * 6e4
|
|
11846
11862
|
);
|
|
@@ -13092,15 +13108,22 @@ const TaskGanttContentInner = (props) => {
|
|
|
13092
13108
|
x2: taskX2,
|
|
13093
13109
|
comparisonDates
|
|
13094
13110
|
} = getTaskCoordinates2(task);
|
|
13111
|
+
const safeContainerX = isNaN(containerX) || !isFinite(containerX) ? 0 : containerX;
|
|
13112
|
+
const safeContainerWidth = isNaN(containerWidth) || !isFinite(containerWidth) ? 0 : Math.max(containerWidth, 0);
|
|
13113
|
+
const safeWidth = isNaN(width) || !isFinite(width) ? 10 : Math.max(width, 1);
|
|
13114
|
+
const safeLevelY = isNaN(levelY) || !isFinite(levelY) ? 0 : levelY;
|
|
13115
|
+
const safeProgressWidth = isNaN(progressWidth) || !isFinite(progressWidth) ? 0 : Math.max(progressWidth, 0);
|
|
13116
|
+
const safeInnerX1 = isNaN(innerX1) || !isFinite(innerX1) ? 0 : innerX1;
|
|
13117
|
+
const safeInnerX2 = isNaN(innerX2) || !isFinite(innerX2) ? safeInnerX1 + safeWidth : innerX2;
|
|
13095
13118
|
tasksRes.push(
|
|
13096
13119
|
/* @__PURE__ */ jsx(
|
|
13097
13120
|
"svg",
|
|
13098
13121
|
{
|
|
13099
13122
|
id: task.id,
|
|
13100
13123
|
className: `${styles$4.TaskItemWrapper} TaskItemWrapper`,
|
|
13101
|
-
x: Math.max(
|
|
13102
|
-
y:
|
|
13103
|
-
width: Math.max(
|
|
13124
|
+
x: Math.max(safeContainerX + (additionalLeftSpace || 0), 0),
|
|
13125
|
+
y: safeLevelY,
|
|
13126
|
+
width: Math.max(safeContainerWidth, 0),
|
|
13104
13127
|
height: fullRowHeight,
|
|
13105
13128
|
children: /* @__PURE__ */ jsx(
|
|
13106
13129
|
TaskItem,
|
|
@@ -13108,14 +13131,14 @@ const TaskGanttContentInner = (props) => {
|
|
|
13108
13131
|
movingAction: taskBarMovingAction(task),
|
|
13109
13132
|
allowMoveTaskBar,
|
|
13110
13133
|
hasChildren: checkHasChildren(task, childTasksMap),
|
|
13111
|
-
progressWidth,
|
|
13112
|
-
progressX: rtl ?
|
|
13134
|
+
progressWidth: safeProgressWidth,
|
|
13135
|
+
progressX: rtl ? safeInnerX2 : safeInnerX1,
|
|
13113
13136
|
onSelectTaskOnMouseDown: selectTaskOnMouseDown,
|
|
13114
13137
|
task,
|
|
13115
13138
|
taskYOffset,
|
|
13116
|
-
width,
|
|
13117
|
-
x1:
|
|
13118
|
-
x2:
|
|
13139
|
+
width: safeWidth,
|
|
13140
|
+
x1: safeInnerX1,
|
|
13141
|
+
x2: safeInnerX2,
|
|
13119
13142
|
distances,
|
|
13120
13143
|
taskHeight,
|
|
13121
13144
|
taskHalfHeight,
|
|
@@ -13145,16 +13168,20 @@ const TaskGanttContentInner = (props) => {
|
|
|
13145
13168
|
)
|
|
13146
13169
|
);
|
|
13147
13170
|
if (task.comparisonDates && comparisonDates) {
|
|
13171
|
+
const safeComparisonX = isNaN(comparisonDates.x) || !isFinite(comparisonDates.x) ? 0 : comparisonDates.x;
|
|
13172
|
+
const safeComparisonY = isNaN(comparisonDates.y) || !isFinite(comparisonDates.y) ? safeLevelY : comparisonDates.y;
|
|
13173
|
+
const safeComparisonWidth = isNaN(comparisonDates.width) || !isFinite(comparisonDates.width) ? 10 : Math.max(comparisonDates.width, 1);
|
|
13174
|
+
const safeComparisonHeight = isNaN(comparisonDates.height) || !isFinite(comparisonDates.height) ? 4 : Math.max(comparisonDates.height, 1);
|
|
13148
13175
|
tasksRes.push(
|
|
13149
13176
|
/* @__PURE__ */ jsx(
|
|
13150
13177
|
"svg",
|
|
13151
13178
|
{
|
|
13152
13179
|
id: task.id + "_comparison",
|
|
13153
13180
|
className: "TaskItemWrapperComparison",
|
|
13154
|
-
x: Math.max(
|
|
13155
|
-
y:
|
|
13156
|
-
width:
|
|
13157
|
-
height:
|
|
13181
|
+
x: Math.max(safeComparisonX + (additionalLeftSpace || 0), 0),
|
|
13182
|
+
y: safeComparisonY,
|
|
13183
|
+
width: safeComparisonWidth,
|
|
13184
|
+
height: safeComparisonHeight * 2,
|
|
13158
13185
|
children: /* @__PURE__ */ jsx(
|
|
13159
13186
|
BarComparison,
|
|
13160
13187
|
{
|
|
@@ -13163,8 +13190,8 @@ const TaskGanttContentInner = (props) => {
|
|
|
13163
13190
|
isWarning: !!task.comparisonDates.end && task.comparisonDates.end.getTime() >= task.end.getTime(),
|
|
13164
13191
|
isCritical: task.comparisonDates.start.getTime() > task.start.getTime(),
|
|
13165
13192
|
barCornerRadius: distances.barCornerRadius,
|
|
13166
|
-
height:
|
|
13167
|
-
width:
|
|
13193
|
+
height: safeComparisonHeight,
|
|
13194
|
+
width: safeComparisonWidth,
|
|
13168
13195
|
borderHeight: distances.barComparisonTaskBorderHeight,
|
|
13169
13196
|
yOffset: distances.barComparisonTaskYOffset,
|
|
13170
13197
|
task,
|
|
@@ -13207,15 +13234,24 @@ const TaskGanttContentInner = (props) => {
|
|
|
13207
13234
|
addedDependenciesAtTask[source.id] = true;
|
|
13208
13235
|
const isCritical2 = criticalPathForTask ? criticalPathForTask.has(source.id) : false;
|
|
13209
13236
|
const { x1: fromX1, x2: fromX2 } = getTaskCoordinates2(source);
|
|
13210
|
-
const
|
|
13211
|
-
const
|
|
13237
|
+
const safeFromX1 = isNaN(fromX1) || !isFinite(fromX1) ? 0 : fromX1;
|
|
13238
|
+
const safeFromX2 = isNaN(fromX2) || !isFinite(fromX2) ? safeFromX1 + 10 : fromX2;
|
|
13239
|
+
const safeTaskX1 = isNaN(taskX1) || !isFinite(taskX1) ? 0 : taskX1;
|
|
13240
|
+
const safeTaskX2 = isNaN(taskX2) || !isFinite(taskX2) ? safeTaskX1 + 10 : taskX2;
|
|
13241
|
+
const containerX2 = Math.min(safeFromX1, safeTaskX1) - DELTA_RELATION_WIDTH;
|
|
13242
|
+
const containerWidth2 = Math.max(safeFromX2, safeTaskX2) - containerX2 + DELTA_RELATION_WIDTH;
|
|
13243
|
+
const safeArrowContainerX = isNaN(containerX2) || !isFinite(containerX2) ? 0 : containerX2;
|
|
13244
|
+
const safeArrowContainerWidth = isNaN(containerWidth2) || !isFinite(containerWidth2) ? 100 : Math.max(containerWidth2, 0);
|
|
13212
13245
|
arrowsRes.push(
|
|
13213
13246
|
/* @__PURE__ */ jsx(
|
|
13214
13247
|
"svg",
|
|
13215
13248
|
{
|
|
13216
|
-
x: Math.max(
|
|
13249
|
+
x: Math.max(
|
|
13250
|
+
safeArrowContainerX + (additionalLeftSpace || 0),
|
|
13251
|
+
0
|
|
13252
|
+
),
|
|
13217
13253
|
y: containerY,
|
|
13218
|
-
width:
|
|
13254
|
+
width: safeArrowContainerWidth,
|
|
13219
13255
|
height: containerHeight,
|
|
13220
13256
|
children: /* @__PURE__ */ jsx(
|
|
13221
13257
|
Arrow,
|
|
@@ -13223,13 +13259,13 @@ const TaskGanttContentInner = (props) => {
|
|
|
13223
13259
|
distances,
|
|
13224
13260
|
taskFrom: source,
|
|
13225
13261
|
targetFrom: sourceTarget,
|
|
13226
|
-
fromX1:
|
|
13227
|
-
fromX2:
|
|
13262
|
+
fromX1: safeFromX1 - safeArrowContainerX,
|
|
13263
|
+
fromX2: safeFromX2 - safeArrowContainerX,
|
|
13228
13264
|
fromY: innerFromY,
|
|
13229
13265
|
taskTo: task,
|
|
13230
13266
|
targetTo: ownTarget,
|
|
13231
|
-
toX1:
|
|
13232
|
-
toX2:
|
|
13267
|
+
toX1: safeTaskX1 - safeArrowContainerX,
|
|
13268
|
+
toX2: safeTaskX2 - safeArrowContainerX,
|
|
13233
13269
|
toY: innerToY,
|
|
13234
13270
|
fullRowHeight,
|
|
13235
13271
|
taskHeight,
|
|
@@ -13272,15 +13308,24 @@ const TaskGanttContentInner = (props) => {
|
|
|
13272
13308
|
const criticalPathForTask = criticalPathOnLevel ? criticalPathOnLevel.dependencies.get(dependent.id) : void 0;
|
|
13273
13309
|
const isCritical2 = criticalPathForTask ? criticalPathForTask.has(task.id) : false;
|
|
13274
13310
|
const { x1: toX1, x2: toX2 } = getTaskCoordinates2(dependent);
|
|
13275
|
-
const
|
|
13276
|
-
const
|
|
13311
|
+
const safeToX1 = isNaN(toX1) || !isFinite(toX1) ? 0 : toX1;
|
|
13312
|
+
const safeToX2 = isNaN(toX2) || !isFinite(toX2) ? safeToX1 + 10 : toX2;
|
|
13313
|
+
const safeTaskX1 = isNaN(taskX1) || !isFinite(taskX1) ? 0 : taskX1;
|
|
13314
|
+
const safeTaskX2 = isNaN(taskX2) || !isFinite(taskX2) ? safeTaskX1 + 10 : taskX2;
|
|
13315
|
+
const containerX2 = Math.min(safeToX1, safeTaskX1) - DELTA_RELATION_WIDTH;
|
|
13316
|
+
const containerWidth2 = Math.max(safeToX2, safeTaskX2) - containerX2 + DELTA_RELATION_WIDTH;
|
|
13317
|
+
const safeArrowContainerX = isNaN(containerX2) || !isFinite(containerX2) ? 0 : containerX2;
|
|
13318
|
+
const safeArrowContainerWidth = isNaN(containerWidth2) || !isFinite(containerWidth2) ? 100 : Math.max(containerWidth2, 0);
|
|
13277
13319
|
arrowsRes.push(
|
|
13278
13320
|
/* @__PURE__ */ jsx(
|
|
13279
13321
|
"svg",
|
|
13280
13322
|
{
|
|
13281
|
-
x: Math.max(
|
|
13323
|
+
x: Math.max(
|
|
13324
|
+
safeArrowContainerX + (additionalLeftSpace || 0),
|
|
13325
|
+
0
|
|
13326
|
+
),
|
|
13282
13327
|
y: containerY,
|
|
13283
|
-
width:
|
|
13328
|
+
width: safeArrowContainerWidth,
|
|
13284
13329
|
height: containerHeight,
|
|
13285
13330
|
children: /* @__PURE__ */ jsx(
|
|
13286
13331
|
Arrow,
|
|
@@ -13288,13 +13333,13 @@ const TaskGanttContentInner = (props) => {
|
|
|
13288
13333
|
distances,
|
|
13289
13334
|
taskFrom: task,
|
|
13290
13335
|
targetFrom: ownTarget,
|
|
13291
|
-
fromX1:
|
|
13292
|
-
fromX2:
|
|
13336
|
+
fromX1: safeTaskX1 - safeArrowContainerX,
|
|
13337
|
+
fromX2: safeTaskX2 - safeArrowContainerX,
|
|
13293
13338
|
fromY: innerFromY,
|
|
13294
13339
|
taskTo: dependent,
|
|
13295
13340
|
targetTo: dependentTarget,
|
|
13296
|
-
toX1:
|
|
13297
|
-
toX2:
|
|
13341
|
+
toX1: safeToX1 - safeArrowContainerX,
|
|
13342
|
+
toX2: safeToX2 - safeArrowContainerX,
|
|
13298
13343
|
toY: innerToY,
|
|
13299
13344
|
fullRowHeight,
|
|
13300
13345
|
taskHeight,
|
|
@@ -13772,21 +13817,26 @@ const countTaskCoordinates = (task, taskToRowIndexMap, startDate, viewMode, rtl,
|
|
|
13772
13817
|
if (typeof rowIndex !== "number") {
|
|
13773
13818
|
throw new Error(`Row index for task ${id} is not found`);
|
|
13774
13819
|
}
|
|
13775
|
-
|
|
13776
|
-
|
|
13820
|
+
let x1 = rtl ? svgWidth - taskXCoordinate(task.end, startDate, viewMode, columnWidth) : taskXCoordinate(task.start, startDate, viewMode, columnWidth);
|
|
13821
|
+
let x2 = rtl ? svgWidth - taskXCoordinate(task.start, startDate, viewMode, columnWidth) : taskXCoordinate(task.end, startDate, viewMode, columnWidth);
|
|
13822
|
+
x1 = isNaN(x1) || !isFinite(x1) ? 0 : x1;
|
|
13823
|
+
x2 = isNaN(x2) || !isFinite(x2) ? Math.max(x1, 10) : x2;
|
|
13777
13824
|
const levelY = rowIndex * fullRowHeight + rowHeight * (comparisonLevel - 1);
|
|
13778
13825
|
const y = levelY + taskYOffset;
|
|
13779
13826
|
const [progressWidth, progressX] = type === "milestone" ? [0, x1] : progressWithByParams(x1, x2, progress, rtl);
|
|
13780
13827
|
const taskX1 = type === "milestone" ? x1 - taskHeight * 0.5 : x1;
|
|
13781
13828
|
const taskX2 = type === "milestone" ? x2 + taskHeight * 0.5 : x2;
|
|
13782
|
-
|
|
13783
|
-
|
|
13784
|
-
|
|
13829
|
+
let taskWidth = type === "milestone" ? taskHeight : Math.max(taskX2 - taskX1, 10);
|
|
13830
|
+
taskWidth = isNaN(taskWidth) || !isFinite(taskWidth) ? 10 : Math.max(taskWidth, 1);
|
|
13831
|
+
let containerX = taskX1 - columnWidth;
|
|
13832
|
+
containerX = isNaN(containerX) || !isFinite(containerX) ? 0 : containerX;
|
|
13833
|
+
let containerWidth = svgWidth - containerX;
|
|
13834
|
+
containerWidth = isNaN(containerWidth) || !isFinite(containerWidth) ? svgWidth : Math.max(containerWidth, 0);
|
|
13785
13835
|
const innerX1 = columnWidth;
|
|
13786
13836
|
const innerX2 = columnWidth + taskWidth;
|
|
13787
13837
|
let comparisonDates;
|
|
13788
13838
|
if (task.comparisonDates) {
|
|
13789
|
-
|
|
13839
|
+
let cx1 = rtl ? svgWidth - taskComparisonXCoordinate(
|
|
13790
13840
|
task.comparisonDates.end || task.end,
|
|
13791
13841
|
startDate,
|
|
13792
13842
|
viewMode,
|
|
@@ -13797,7 +13847,7 @@ const countTaskCoordinates = (task, taskToRowIndexMap, startDate, viewMode, rtl,
|
|
|
13797
13847
|
viewMode,
|
|
13798
13848
|
columnWidth
|
|
13799
13849
|
);
|
|
13800
|
-
|
|
13850
|
+
let cx2 = rtl ? svgWidth - taskComparisonXCoordinate(
|
|
13801
13851
|
task.comparisonDates.start,
|
|
13802
13852
|
startDate,
|
|
13803
13853
|
viewMode,
|
|
@@ -13808,10 +13858,13 @@ const countTaskCoordinates = (task, taskToRowIndexMap, startDate, viewMode, rtl,
|
|
|
13808
13858
|
viewMode,
|
|
13809
13859
|
columnWidth
|
|
13810
13860
|
);
|
|
13861
|
+
cx1 = isNaN(cx1) || !isFinite(cx1) ? x1 : cx1;
|
|
13862
|
+
cx2 = isNaN(cx2) || !isFinite(cx2) ? x2 : cx2;
|
|
13811
13863
|
comparisonDates = {
|
|
13812
13864
|
x: cx1,
|
|
13813
13865
|
y: y + taskHeight,
|
|
13814
|
-
width: Math.max(cx2 - cx1,
|
|
13866
|
+
width: Math.max(cx2 - cx1, 1),
|
|
13867
|
+
// Ensure minimum width of 1px for visibility
|
|
13815
13868
|
height: barComparisonTaskHeight
|
|
13816
13869
|
};
|
|
13817
13870
|
}
|
|
@@ -17486,308 +17539,6 @@ const useHorizontalScrollbars = () => {
|
|
|
17486
17539
|
scrollToRightStep
|
|
17487
17540
|
];
|
|
17488
17541
|
};
|
|
17489
|
-
const usePerformanceMonitor = (enabled = true) => {
|
|
17490
|
-
const metricsRef = useRef([]);
|
|
17491
|
-
const benchmarksRef = useRef(/* @__PURE__ */ new Map());
|
|
17492
|
-
const frameTimesRef = useRef([]);
|
|
17493
|
-
const lastFrameTimeRef = useRef(performance.now());
|
|
17494
|
-
const updateFPS = useCallback(() => {
|
|
17495
|
-
if (!enabled)
|
|
17496
|
-
return;
|
|
17497
|
-
const now = performance.now();
|
|
17498
|
-
const deltaTime = now - lastFrameTimeRef.current;
|
|
17499
|
-
lastFrameTimeRef.current = now;
|
|
17500
|
-
frameTimesRef.current.push(deltaTime);
|
|
17501
|
-
if (frameTimesRef.current.length > 60) {
|
|
17502
|
-
frameTimesRef.current.shift();
|
|
17503
|
-
}
|
|
17504
|
-
}, [enabled]);
|
|
17505
|
-
const getFPS = useCallback(() => {
|
|
17506
|
-
if (frameTimesRef.current.length === 0)
|
|
17507
|
-
return 0;
|
|
17508
|
-
const avgFrameTime = frameTimesRef.current.reduce((sum, time) => sum + time, 0) / frameTimesRef.current.length;
|
|
17509
|
-
return Math.round(1e3 / avgFrameTime);
|
|
17510
|
-
}, []);
|
|
17511
|
-
const startMeasurement = useCallback(
|
|
17512
|
-
(name, metadata) => {
|
|
17513
|
-
if (!enabled)
|
|
17514
|
-
return;
|
|
17515
|
-
performance.mark(`${name}-start`);
|
|
17516
|
-
benchmarksRef.current.set(name, {
|
|
17517
|
-
name,
|
|
17518
|
-
startTime: performance.now(),
|
|
17519
|
-
metadata
|
|
17520
|
-
});
|
|
17521
|
-
},
|
|
17522
|
-
[enabled]
|
|
17523
|
-
);
|
|
17524
|
-
const endMeasurement = useCallback(
|
|
17525
|
-
(name) => {
|
|
17526
|
-
if (!enabled)
|
|
17527
|
-
return 0;
|
|
17528
|
-
const benchmark = benchmarksRef.current.get(name);
|
|
17529
|
-
if (!benchmark) {
|
|
17530
|
-
console.warn(`No benchmark found for ${name}`);
|
|
17531
|
-
return 0;
|
|
17532
|
-
}
|
|
17533
|
-
const endTime = performance.now();
|
|
17534
|
-
const duration = endTime - benchmark.startTime;
|
|
17535
|
-
performance.mark(`${name}-end`);
|
|
17536
|
-
performance.measure(name, `${name}-start`, `${name}-end`);
|
|
17537
|
-
benchmark.endTime = endTime;
|
|
17538
|
-
benchmark.duration = duration;
|
|
17539
|
-
return duration;
|
|
17540
|
-
},
|
|
17541
|
-
[enabled]
|
|
17542
|
-
);
|
|
17543
|
-
const measureFunction = useCallback(
|
|
17544
|
-
(name, fn, metadata) => {
|
|
17545
|
-
return (...args) => {
|
|
17546
|
-
if (!enabled)
|
|
17547
|
-
return fn(...args);
|
|
17548
|
-
startMeasurement(name, metadata);
|
|
17549
|
-
try {
|
|
17550
|
-
const result = fn(...args);
|
|
17551
|
-
return result;
|
|
17552
|
-
} finally {
|
|
17553
|
-
endMeasurement(name);
|
|
17554
|
-
}
|
|
17555
|
-
};
|
|
17556
|
-
},
|
|
17557
|
-
[enabled, startMeasurement, endMeasurement]
|
|
17558
|
-
);
|
|
17559
|
-
const measureAsyncFunction = useCallback(
|
|
17560
|
-
(name, fn, metadata) => {
|
|
17561
|
-
return async (...args) => {
|
|
17562
|
-
if (!enabled)
|
|
17563
|
-
return fn(...args);
|
|
17564
|
-
startMeasurement(name, metadata);
|
|
17565
|
-
try {
|
|
17566
|
-
const result = await fn(...args);
|
|
17567
|
-
return result;
|
|
17568
|
-
} finally {
|
|
17569
|
-
endMeasurement(name);
|
|
17570
|
-
}
|
|
17571
|
-
};
|
|
17572
|
-
},
|
|
17573
|
-
[enabled, startMeasurement, endMeasurement]
|
|
17574
|
-
);
|
|
17575
|
-
const getPerformanceReport = useCallback(() => {
|
|
17576
|
-
const entries = performance.getEntriesByType(
|
|
17577
|
-
"measure"
|
|
17578
|
-
);
|
|
17579
|
-
const report = {};
|
|
17580
|
-
entries.forEach((entry) => {
|
|
17581
|
-
if (!report[entry.name]) {
|
|
17582
|
-
report[entry.name] = {
|
|
17583
|
-
count: 0,
|
|
17584
|
-
totalTime: 0,
|
|
17585
|
-
avgTime: 0,
|
|
17586
|
-
maxTime: 0,
|
|
17587
|
-
minTime: Infinity
|
|
17588
|
-
};
|
|
17589
|
-
}
|
|
17590
|
-
const stat = report[entry.name];
|
|
17591
|
-
stat.count++;
|
|
17592
|
-
stat.totalTime += entry.duration;
|
|
17593
|
-
stat.maxTime = Math.max(stat.maxTime, entry.duration);
|
|
17594
|
-
stat.minTime = Math.min(stat.minTime, entry.duration);
|
|
17595
|
-
stat.avgTime = stat.totalTime / stat.count;
|
|
17596
|
-
});
|
|
17597
|
-
return {
|
|
17598
|
-
measurements: report,
|
|
17599
|
-
fps: getFPS(),
|
|
17600
|
-
currentMetrics: metricsRef.current[metricsRef.current.length - 1],
|
|
17601
|
-
allMetrics: [...metricsRef.current]
|
|
17602
|
-
};
|
|
17603
|
-
}, [getFPS]);
|
|
17604
|
-
const addMetrics = useCallback(
|
|
17605
|
-
(metrics) => {
|
|
17606
|
-
if (!enabled)
|
|
17607
|
-
return;
|
|
17608
|
-
const fullMetrics = {
|
|
17609
|
-
...metrics,
|
|
17610
|
-
timestamp: Date.now()
|
|
17611
|
-
};
|
|
17612
|
-
metricsRef.current.push(fullMetrics);
|
|
17613
|
-
if (metricsRef.current.length > 100) {
|
|
17614
|
-
metricsRef.current.shift();
|
|
17615
|
-
}
|
|
17616
|
-
},
|
|
17617
|
-
[enabled]
|
|
17618
|
-
);
|
|
17619
|
-
const clearMeasurements = useCallback(() => {
|
|
17620
|
-
performance.clearMarks();
|
|
17621
|
-
performance.clearMeasures();
|
|
17622
|
-
benchmarksRef.current.clear();
|
|
17623
|
-
metricsRef.current.length = 0;
|
|
17624
|
-
frameTimesRef.current.length = 0;
|
|
17625
|
-
}, []);
|
|
17626
|
-
const getMemoryUsage = useCallback(() => {
|
|
17627
|
-
if ("memory" in performance) {
|
|
17628
|
-
const memory = performance.memory;
|
|
17629
|
-
return memory ? memory.usedJSHeapSize : 0;
|
|
17630
|
-
}
|
|
17631
|
-
return 0;
|
|
17632
|
-
}, []);
|
|
17633
|
-
return {
|
|
17634
|
-
startMeasurement,
|
|
17635
|
-
endMeasurement,
|
|
17636
|
-
measureFunction,
|
|
17637
|
-
measureAsyncFunction,
|
|
17638
|
-
getPerformanceReport,
|
|
17639
|
-
addMetrics,
|
|
17640
|
-
clearMeasurements,
|
|
17641
|
-
updateFPS,
|
|
17642
|
-
getFPS,
|
|
17643
|
-
getMemoryUsage,
|
|
17644
|
-
enabled
|
|
17645
|
-
};
|
|
17646
|
-
};
|
|
17647
|
-
const useAdaptivePerformance = (thresholds) => {
|
|
17648
|
-
const { getFPS, getPerformanceReport } = usePerformanceMonitor();
|
|
17649
|
-
const performanceLevelRef = useRef("high");
|
|
17650
|
-
const updatePerformanceLevel = useCallback(() => {
|
|
17651
|
-
var _a;
|
|
17652
|
-
const fps = getFPS();
|
|
17653
|
-
const report = getPerformanceReport();
|
|
17654
|
-
const renderTime = ((_a = report.measurements["render"]) == null ? void 0 : _a.avgTime) || 0;
|
|
17655
|
-
if (fps < thresholds.fpsThreshold * 0.5 || renderTime > thresholds.renderTimeThreshold * 2) {
|
|
17656
|
-
performanceLevelRef.current = "low";
|
|
17657
|
-
} else if (fps < thresholds.fpsThreshold || renderTime > thresholds.renderTimeThreshold) {
|
|
17658
|
-
performanceLevelRef.current = "medium";
|
|
17659
|
-
} else {
|
|
17660
|
-
performanceLevelRef.current = "high";
|
|
17661
|
-
}
|
|
17662
|
-
return performanceLevelRef.current;
|
|
17663
|
-
}, [getFPS, getPerformanceReport, thresholds]);
|
|
17664
|
-
const getQualitySettings = useCallback(() => {
|
|
17665
|
-
const level = performanceLevelRef.current;
|
|
17666
|
-
switch (level) {
|
|
17667
|
-
case "low":
|
|
17668
|
-
return {
|
|
17669
|
-
enableAnimations: false,
|
|
17670
|
-
renderQuality: "low",
|
|
17671
|
-
maxVisibleTasks: 100,
|
|
17672
|
-
updateFrequency: 500
|
|
17673
|
-
// ms
|
|
17674
|
-
};
|
|
17675
|
-
case "medium":
|
|
17676
|
-
return {
|
|
17677
|
-
enableAnimations: true,
|
|
17678
|
-
renderQuality: "medium",
|
|
17679
|
-
maxVisibleTasks: 500,
|
|
17680
|
-
updateFrequency: 100
|
|
17681
|
-
};
|
|
17682
|
-
case "high":
|
|
17683
|
-
default:
|
|
17684
|
-
return {
|
|
17685
|
-
enableAnimations: true,
|
|
17686
|
-
renderQuality: "high",
|
|
17687
|
-
maxVisibleTasks: 1e3,
|
|
17688
|
-
updateFrequency: 16
|
|
17689
|
-
// 60fps
|
|
17690
|
-
};
|
|
17691
|
-
}
|
|
17692
|
-
}, []);
|
|
17693
|
-
return {
|
|
17694
|
-
performanceLevel: performanceLevelRef.current,
|
|
17695
|
-
updatePerformanceLevel,
|
|
17696
|
-
getQualitySettings
|
|
17697
|
-
};
|
|
17698
|
-
};
|
|
17699
|
-
const useIncrementalCoordinates = (visibleTasks, visibleTasksMirror, taskToRowIndexMap, startDate, viewMode, rtl, fullRowHeight, taskHeight, taskYOffset, distances, svgWidth, renderedRowIndexes, renderedColumnIndexes) => {
|
|
17700
|
-
const cacheRef = useRef({
|
|
17701
|
-
coordinates: /* @__PURE__ */ new Map(),
|
|
17702
|
-
lastUpdateParams: null
|
|
17703
|
-
});
|
|
17704
|
-
return useMemo(() => {
|
|
17705
|
-
const cache = cacheRef.current;
|
|
17706
|
-
const currentParams = {
|
|
17707
|
-
startDate,
|
|
17708
|
-
viewMode,
|
|
17709
|
-
rtl,
|
|
17710
|
-
fullRowHeight,
|
|
17711
|
-
taskHeight,
|
|
17712
|
-
taskYOffset,
|
|
17713
|
-
svgWidth,
|
|
17714
|
-
distances
|
|
17715
|
-
};
|
|
17716
|
-
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);
|
|
17717
|
-
if (needsFullRecalc) {
|
|
17718
|
-
cache.coordinates.clear();
|
|
17719
|
-
}
|
|
17720
|
-
const tasksToCalculate = /* @__PURE__ */ new Set();
|
|
17721
|
-
if (renderedRowIndexes && renderedColumnIndexes) {
|
|
17722
|
-
const [startRow, endRow] = renderedRowIndexes;
|
|
17723
|
-
const rowBuffer = Math.max(5, Math.ceil((endRow - startRow) * 0.5));
|
|
17724
|
-
const bufferedStartRow = Math.max(0, startRow - rowBuffer);
|
|
17725
|
-
const bufferedEndRow = endRow + rowBuffer;
|
|
17726
|
-
visibleTasks.forEach((task, index2) => {
|
|
17727
|
-
if (task.type === "empty" || !visibleTasksMirror[task.id])
|
|
17728
|
-
return;
|
|
17729
|
-
if (index2 >= bufferedStartRow && index2 <= bufferedEndRow) {
|
|
17730
|
-
tasksToCalculate.add(task.id);
|
|
17731
|
-
}
|
|
17732
|
-
});
|
|
17733
|
-
} else {
|
|
17734
|
-
visibleTasks.forEach((task) => {
|
|
17735
|
-
if (task.type !== "empty" && visibleTasksMirror[task.id]) {
|
|
17736
|
-
tasksToCalculate.add(task.id);
|
|
17737
|
-
}
|
|
17738
|
-
});
|
|
17739
|
-
}
|
|
17740
|
-
if (!needsFullRecalc) {
|
|
17741
|
-
for (const [taskId] of cache.coordinates) {
|
|
17742
|
-
if (!tasksToCalculate.has(taskId)) {
|
|
17743
|
-
cache.coordinates.delete(taskId);
|
|
17744
|
-
}
|
|
17745
|
-
}
|
|
17746
|
-
}
|
|
17747
|
-
const res = /* @__PURE__ */ new Map();
|
|
17748
|
-
visibleTasks.forEach((task) => {
|
|
17749
|
-
if (task.type === "empty" || !tasksToCalculate.has(task.id))
|
|
17750
|
-
return;
|
|
17751
|
-
const { id, comparisonLevel = 1 } = task;
|
|
17752
|
-
const cacheKey = `${id}_${comparisonLevel}`;
|
|
17753
|
-
let taskCoordinates = cache.coordinates.get(cacheKey);
|
|
17754
|
-
if (!taskCoordinates || needsFullRecalc) {
|
|
17755
|
-
taskCoordinates = countTaskCoordinates(
|
|
17756
|
-
task,
|
|
17757
|
-
taskToRowIndexMap,
|
|
17758
|
-
startDate,
|
|
17759
|
-
viewMode,
|
|
17760
|
-
rtl,
|
|
17761
|
-
fullRowHeight,
|
|
17762
|
-
taskHeight,
|
|
17763
|
-
taskYOffset,
|
|
17764
|
-
distances,
|
|
17765
|
-
svgWidth
|
|
17766
|
-
);
|
|
17767
|
-
cache.coordinates.set(cacheKey, taskCoordinates);
|
|
17768
|
-
}
|
|
17769
|
-
const resByLevel = res.get(comparisonLevel) || /* @__PURE__ */ new Map();
|
|
17770
|
-
resByLevel.set(id, taskCoordinates);
|
|
17771
|
-
res.set(comparisonLevel, resByLevel);
|
|
17772
|
-
});
|
|
17773
|
-
cache.lastUpdateParams = currentParams;
|
|
17774
|
-
return res;
|
|
17775
|
-
}, [
|
|
17776
|
-
visibleTasks,
|
|
17777
|
-
visibleTasksMirror,
|
|
17778
|
-
taskToRowIndexMap,
|
|
17779
|
-
startDate,
|
|
17780
|
-
viewMode,
|
|
17781
|
-
rtl,
|
|
17782
|
-
fullRowHeight,
|
|
17783
|
-
taskHeight,
|
|
17784
|
-
taskYOffset,
|
|
17785
|
-
distances,
|
|
17786
|
-
svgWidth,
|
|
17787
|
-
renderedRowIndexes,
|
|
17788
|
-
renderedColumnIndexes
|
|
17789
|
-
]);
|
|
17790
|
-
};
|
|
17791
17542
|
const fillMinAndMaxChildsMap = (resOnLevel, task, childTasksOnLevel) => {
|
|
17792
17543
|
const childs = childTasksOnLevel.get(task.id);
|
|
17793
17544
|
if (!childs || childs.length === 0) {
|
|
@@ -19407,11 +19158,6 @@ const Gantt = (props) => {
|
|
|
19407
19158
|
() => getChildsAndRoots(sortedTasks, null),
|
|
19408
19159
|
[sortedTasks]
|
|
19409
19160
|
);
|
|
19410
|
-
const adaptiveSettings = useAdaptivePerformance({
|
|
19411
|
-
fpsThreshold: 30,
|
|
19412
|
-
renderTimeThreshold: 16
|
|
19413
|
-
// 60fps = 16ms per frame
|
|
19414
|
-
});
|
|
19415
19161
|
const minAndMaxChildsMap = useMemo(
|
|
19416
19162
|
() => getMinAndMaxChildsMap(rootTasksMap, childTasksMap),
|
|
19417
19163
|
[rootTasksMap, childTasksMap]
|
|
@@ -19585,7 +19331,7 @@ const Gantt = (props) => {
|
|
|
19585
19331
|
svgWidth
|
|
19586
19332
|
]
|
|
19587
19333
|
);
|
|
19588
|
-
const
|
|
19334
|
+
const mapTaskToCoordinates = useMemo(
|
|
19589
19335
|
() => getMapTaskToCoordinates(
|
|
19590
19336
|
sortedTasks,
|
|
19591
19337
|
visibleTasksMirror,
|
|
@@ -19613,24 +19359,6 @@ const Gantt = (props) => {
|
|
|
19613
19359
|
visibleTasksMirror
|
|
19614
19360
|
]
|
|
19615
19361
|
);
|
|
19616
|
-
const optimizedMapTaskToCoordinates = useIncrementalCoordinates(
|
|
19617
|
-
visibleTasks,
|
|
19618
|
-
visibleTasksMirror,
|
|
19619
|
-
taskToRowIndexMap,
|
|
19620
|
-
startDate,
|
|
19621
|
-
viewMode,
|
|
19622
|
-
rtl,
|
|
19623
|
-
fullRowHeight,
|
|
19624
|
-
taskHeight,
|
|
19625
|
-
taskYOffset,
|
|
19626
|
-
distances,
|
|
19627
|
-
svgWidth,
|
|
19628
|
-
null,
|
|
19629
|
-
// renderedRowIndexes - can be integrated later with virtualization
|
|
19630
|
-
null
|
|
19631
|
-
// renderedColumnIndexes - can be integrated later with virtualization
|
|
19632
|
-
);
|
|
19633
|
-
const mapTaskToCoordinates = adaptiveSettings.performanceLevel === "high" ? optimizedMapTaskToCoordinates : originalMapTaskToCoordinates;
|
|
19634
19362
|
const scrollToTask = useCallback(
|
|
19635
19363
|
(task) => {
|
|
19636
19364
|
const { x1 } = getTaskCoordinates(task, mapTaskToCoordinates);
|