gantt-task-react-v 1.3.2 → 1.3.3

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.
@@ -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 percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
11822
- return index2 * columnWidth + percentOfInterval * columnWidth;
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 percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
11830
- return index2 * columnWidth + percentOfInterval * columnWidth;
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 progressWidth = Math.max((taskX2 - taskX1) * progress * 0.01, 0);
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 = taskX2 - progressWidth;
11846
+ progressX = safeTaskX2 - progressWidth;
11837
11847
  } else {
11838
- progressX = taskX1;
11848
+ progressX = safeTaskX1;
11839
11849
  }
11840
11850
  return [progressWidth, progressX];
11841
11851
  };
11842
11852
  const dateByX = (x, taskX, taskDate, xStep, timeStep) => {
11843
- let newDate = new Date((x - taskX) / xStep * timeStep + taskDate.getTime());
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(containerX + (additionalLeftSpace || 0), 0),
13102
- y: levelY,
13103
- width: Math.max(containerWidth, 0),
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 ? innerX2 : innerX1,
13134
+ progressWidth: safeProgressWidth,
13135
+ progressX: rtl ? safeInnerX2 : safeInnerX1,
13113
13136
  onSelectTaskOnMouseDown: selectTaskOnMouseDown,
13114
13137
  task,
13115
13138
  taskYOffset,
13116
- width,
13117
- x1: innerX1,
13118
- x2: innerX2,
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) ? 0 : Math.max(comparisonDates.width, 0);
13174
+ const safeComparisonHeight = isNaN(comparisonDates.height) || !isFinite(comparisonDates.height) ? 0 : Math.max(comparisonDates.height, 0);
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(comparisonDates.x + (additionalLeftSpace || 0), 0),
13155
- y: comparisonDates.y,
13156
- width: comparisonDates.width,
13157
- height: comparisonDates.height * 2,
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: comparisonDates.height,
13167
- width: comparisonDates.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 containerX2 = Math.min(fromX1, taskX1) - DELTA_RELATION_WIDTH;
13211
- const containerWidth2 = Math.max(fromX2, taskX2) - containerX2 + DELTA_RELATION_WIDTH;
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(containerX2 + (additionalLeftSpace || 0), 0),
13249
+ x: Math.max(
13250
+ safeArrowContainerX + (additionalLeftSpace || 0),
13251
+ 0
13252
+ ),
13217
13253
  y: containerY,
13218
- width: containerWidth2,
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: fromX1 - containerX2,
13227
- fromX2: fromX2 - containerX2,
13262
+ fromX1: safeFromX1 - safeArrowContainerX,
13263
+ fromX2: safeFromX2 - safeArrowContainerX,
13228
13264
  fromY: innerFromY,
13229
13265
  taskTo: task,
13230
13266
  targetTo: ownTarget,
13231
- toX1: taskX1 - containerX2,
13232
- toX2: taskX2 - containerX2,
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 containerX2 = Math.min(toX1, taskX1) - DELTA_RELATION_WIDTH;
13276
- const containerWidth2 = Math.max(toX2, taskX2) - containerX2 + DELTA_RELATION_WIDTH;
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(containerX2 + (additionalLeftSpace || 0), 0),
13323
+ x: Math.max(
13324
+ safeArrowContainerX + (additionalLeftSpace || 0),
13325
+ 0
13326
+ ),
13282
13327
  y: containerY,
13283
- width: containerWidth2,
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: taskX1 - containerX2,
13292
- fromX2: taskX2 - containerX2,
13336
+ fromX1: safeTaskX1 - safeArrowContainerX,
13337
+ fromX2: safeTaskX2 - safeArrowContainerX,
13293
13338
  fromY: innerFromY,
13294
13339
  taskTo: dependent,
13295
13340
  targetTo: dependentTarget,
13296
- toX1: toX1 - containerX2,
13297
- toX2: toX2 - containerX2,
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
- const x1 = rtl ? svgWidth - taskXCoordinate(task.end, startDate, viewMode, columnWidth) : taskXCoordinate(task.start, startDate, viewMode, columnWidth);
13776
- const x2 = rtl ? svgWidth - taskXCoordinate(task.start, startDate, viewMode, columnWidth) : taskXCoordinate(task.end, startDate, viewMode, columnWidth);
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
- const taskWidth = type === "milestone" ? taskHeight : Math.max(taskX2 - taskX1, 10);
13783
- const containerX = taskX1 - columnWidth;
13784
- const containerWidth = svgWidth - containerX;
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
- const cx1 = rtl ? svgWidth - taskComparisonXCoordinate(
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
- const cx2 = rtl ? svgWidth - taskComparisonXCoordinate(
13850
+ let cx2 = rtl ? svgWidth - taskComparisonXCoordinate(
13801
13851
  task.comparisonDates.start,
13802
13852
  startDate,
13803
13853
  viewMode,
@@ -13808,6 +13858,8 @@ 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,
@@ -17486,308 +17538,6 @@ const useHorizontalScrollbars = () => {
17486
17538
  scrollToRightStep
17487
17539
  ];
17488
17540
  };
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
17541
  const fillMinAndMaxChildsMap = (resOnLevel, task, childTasksOnLevel) => {
17792
17542
  const childs = childTasksOnLevel.get(task.id);
17793
17543
  if (!childs || childs.length === 0) {
@@ -19407,11 +19157,6 @@ const Gantt = (props) => {
19407
19157
  () => getChildsAndRoots(sortedTasks, null),
19408
19158
  [sortedTasks]
19409
19159
  );
19410
- const adaptiveSettings = useAdaptivePerformance({
19411
- fpsThreshold: 30,
19412
- renderTimeThreshold: 16
19413
- // 60fps = 16ms per frame
19414
- });
19415
19160
  const minAndMaxChildsMap = useMemo(
19416
19161
  () => getMinAndMaxChildsMap(rootTasksMap, childTasksMap),
19417
19162
  [rootTasksMap, childTasksMap]
@@ -19585,7 +19330,7 @@ const Gantt = (props) => {
19585
19330
  svgWidth
19586
19331
  ]
19587
19332
  );
19588
- const originalMapTaskToCoordinates = useMemo(
19333
+ const mapTaskToCoordinates = useMemo(
19589
19334
  () => getMapTaskToCoordinates(
19590
19335
  sortedTasks,
19591
19336
  visibleTasksMirror,
@@ -19613,24 +19358,6 @@ const Gantt = (props) => {
19613
19358
  visibleTasksMirror
19614
19359
  ]
19615
19360
  );
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
19361
  const scrollToTask = useCallback(
19635
19362
  (task) => {
19636
19363
  const { x1 } = getTaskCoordinates(task, mapTaskToCoordinates);