gantt-canvas-chart 1.5.2 → 1.5.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.
package/dist/index.cjs.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * gantt-canvas-chart v1.5.2
2
+ * gantt-canvas-chart v1.5.3
3
3
  * (c) 2025-present chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -155,7 +155,9 @@ class GanttChart {
155
155
  onDataLoad = null;
156
156
  scrollLoadTimer = null;
157
157
  constructor(rootContainer, data, config = {}) {
158
- if (rootContainer.querySelector(".__gantt-chart-container")) {
158
+ if (!rootContainer) {
159
+ throw new Error("Root container element is required");
160
+ } else if (rootContainer.querySelector(".__gantt-chart-container")) {
159
161
  throw new Error("GanttChart already exists in this container");
160
162
  }
161
163
  const container = document.createElement("div");
@@ -251,8 +253,18 @@ class GanttChart {
251
253
  }
252
254
  buildTaskMap() {
253
255
  this.taskMap.clear();
254
- this.data.forEach((row, rowIndex) => {
255
- row.tasks.forEach((task) => this.taskMap.set(task.id, { row: rowIndex, task }));
256
+ let visibleRowIndex = 0;
257
+ this.data.forEach((row) => {
258
+ row.tasks.forEach((task) => {
259
+ this.taskMap.set(task.id, {
260
+ row: row.hide ? -1 : visibleRowIndex,
261
+ // Use -1 for hidden rows
262
+ task
263
+ });
264
+ });
265
+ if (!row.hide) {
266
+ visibleRowIndex++;
267
+ }
256
268
  });
257
269
  }
258
270
  setupEvents() {
@@ -521,10 +533,12 @@ class GanttChart {
521
533
  end: this.xToDate(this.scrollLeft + this.viewportWidth + buffer)
522
534
  };
523
535
  }
536
+ // Update the updateDimensions method to calculate height based on visible rows
524
537
  updateDimensions() {
525
538
  const totalDays = DateUtils.diffDays(this.timelineStart, this.timelineEnd) + 1;
539
+ const visibleRowCount = this.data.filter((row) => !row.hide).length;
526
540
  const newTotalWidth = totalDays * this.pixelsPerDay;
527
- const newTotalHeight = this.data.length * this.config.rowHeight + this.config.headerHeight;
541
+ const newTotalHeight = visibleRowCount * this.config.rowHeight + this.config.headerHeight;
528
542
  if (this.totalWidth !== newTotalWidth || this.totalHeight !== newTotalHeight) {
529
543
  this.totalWidth = newTotalWidth;
530
544
  this.totalHeight = newTotalHeight;
@@ -543,12 +557,13 @@ class GanttChart {
543
557
  }
544
558
  calculateAllTaskPositions() {
545
559
  this.taskPositions.clear();
546
- for (let i = 0; i < this.data.length; i++) {
560
+ let visibleRowIndex = 0;
561
+ for (let i = 0, len = this.data.length; i < len; i++) {
547
562
  const row = this.data[i];
548
563
  if (row.hide) {
549
564
  continue;
550
565
  }
551
- const y = i * this.config.rowHeight;
566
+ const y = visibleRowIndex * this.config.rowHeight;
552
567
  row.tasks.forEach((task) => {
553
568
  if (task.hide) {
554
569
  return;
@@ -592,9 +607,11 @@ class GanttChart {
592
607
  x_plan_width,
593
608
  x_actual_width,
594
609
  y: y + this.config.rowHeight * 0.5,
595
- row: i
610
+ row: visibleRowIndex
611
+ // Use visible row index instead of original index
596
612
  });
597
613
  });
614
+ visibleRowIndex++;
598
615
  }
599
616
  }
600
617
  getIterationStartDate(date) {
@@ -884,10 +901,17 @@ class GanttChart {
884
901
  ctx.font = '12px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
885
902
  ctx.textRendering = "optimizeSpeed";
886
903
  ctx.imageSmoothingEnabled = false;
904
+ let visibleRowIndex = 0;
887
905
  for (let i = 0; i < this.data.length; i++) {
888
906
  const row = this.data[i];
889
- const y = i * this.config.rowHeight;
890
- if (y + this.config.rowHeight < this.scrollTop || y > this.scrollTop + this.viewportHeight) continue;
907
+ if (row.hide) {
908
+ continue;
909
+ }
910
+ const y = visibleRowIndex * this.config.rowHeight;
911
+ if (y + this.config.rowHeight < this.scrollTop || y > this.scrollTop + this.viewportHeight) {
912
+ visibleRowIndex++;
913
+ continue;
914
+ }
891
915
  row.tasks.forEach((task) => {
892
916
  const pos = this.taskPositions.get(task.id);
893
917
  if (!pos) return;
@@ -896,14 +920,22 @@ class GanttChart {
896
920
  if (!isPlanVisible && !isActualVisible) return;
897
921
  this.drawTask(ctx, task, y, pos);
898
922
  });
923
+ visibleRowIndex++;
899
924
  }
900
925
  }
926
+ // In the drawGrid method
901
927
  drawGrid(ctx, startDate, endDate) {
902
928
  ctx.strokeStyle = "#e6e6e6";
903
929
  ctx.lineWidth = 1;
904
930
  ctx.beginPath();
905
931
  if (this.config.showRowLines) {
906
- for (let i = 0; i <= this.data.length; i++) {
932
+ let visibleRowCount = 0;
933
+ for (let i = 0; i < this.data.length; i++) {
934
+ if (!this.data[i].hide) {
935
+ visibleRowCount++;
936
+ }
937
+ }
938
+ for (let i = 0; i <= visibleRowCount; i++) {
907
939
  const y = i * this.config.rowHeight;
908
940
  if (y < this.scrollTop || y > this.scrollTop + this.viewportHeight) continue;
909
941
  ctx.moveTo(this.scrollLeft, y);
@@ -1048,10 +1080,21 @@ class GanttChart {
1048
1080
  const mouseY = e.clientY - rect.top;
1049
1081
  const chartX = mouseX + this.scrollLeft;
1050
1082
  const chartY = mouseY + this.scrollTop;
1051
- const rowIndex = Math.floor(chartY / this.config.rowHeight);
1083
+ const visibleRowIndex = Math.floor(chartY / this.config.rowHeight);
1084
+ let actualRowIndex = -1;
1085
+ let visibleRowCount = 0;
1086
+ for (let i = 0; i < this.data.length; i++) {
1087
+ if (!this.data[i].hide) {
1088
+ if (visibleRowCount === visibleRowIndex) {
1089
+ actualRowIndex = i;
1090
+ break;
1091
+ }
1092
+ visibleRowCount++;
1093
+ }
1094
+ }
1052
1095
  const date = this.xToDate(chartX);
1053
- if (rowIndex < 0 || rowIndex >= this.data.length) return this.handleMouseLeave();
1054
- const row = this.data[rowIndex];
1096
+ if (actualRowIndex < 0 || actualRowIndex >= this.data.length) return this.handleMouseLeave();
1097
+ const row = this.data[actualRowIndex];
1055
1098
  if (this.config.tooltipFormat) {
1056
1099
  const htmlStr = this.config.tooltipFormat(row, date, this.config);
1057
1100
  if (!htmlStr) {
package/dist/index.css CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * gantt-canvas-chart v1.5.2
2
+ * gantt-canvas-chart v1.5.3
3
3
  * (c) 2025-present chandq
4
4
  * Released under the MIT License.
5
5
  */
package/dist/index.es.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * gantt-canvas-chart v1.5.2
2
+ * gantt-canvas-chart v1.5.3
3
3
  * (c) 2025-present chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -153,7 +153,9 @@ class GanttChart {
153
153
  onDataLoad = null;
154
154
  scrollLoadTimer = null;
155
155
  constructor(rootContainer, data, config = {}) {
156
- if (rootContainer.querySelector(".__gantt-chart-container")) {
156
+ if (!rootContainer) {
157
+ throw new Error("Root container element is required");
158
+ } else if (rootContainer.querySelector(".__gantt-chart-container")) {
157
159
  throw new Error("GanttChart already exists in this container");
158
160
  }
159
161
  const container = document.createElement("div");
@@ -249,8 +251,18 @@ class GanttChart {
249
251
  }
250
252
  buildTaskMap() {
251
253
  this.taskMap.clear();
252
- this.data.forEach((row, rowIndex) => {
253
- row.tasks.forEach((task) => this.taskMap.set(task.id, { row: rowIndex, task }));
254
+ let visibleRowIndex = 0;
255
+ this.data.forEach((row) => {
256
+ row.tasks.forEach((task) => {
257
+ this.taskMap.set(task.id, {
258
+ row: row.hide ? -1 : visibleRowIndex,
259
+ // Use -1 for hidden rows
260
+ task
261
+ });
262
+ });
263
+ if (!row.hide) {
264
+ visibleRowIndex++;
265
+ }
254
266
  });
255
267
  }
256
268
  setupEvents() {
@@ -519,10 +531,12 @@ class GanttChart {
519
531
  end: this.xToDate(this.scrollLeft + this.viewportWidth + buffer)
520
532
  };
521
533
  }
534
+ // Update the updateDimensions method to calculate height based on visible rows
522
535
  updateDimensions() {
523
536
  const totalDays = DateUtils.diffDays(this.timelineStart, this.timelineEnd) + 1;
537
+ const visibleRowCount = this.data.filter((row) => !row.hide).length;
524
538
  const newTotalWidth = totalDays * this.pixelsPerDay;
525
- const newTotalHeight = this.data.length * this.config.rowHeight + this.config.headerHeight;
539
+ const newTotalHeight = visibleRowCount * this.config.rowHeight + this.config.headerHeight;
526
540
  if (this.totalWidth !== newTotalWidth || this.totalHeight !== newTotalHeight) {
527
541
  this.totalWidth = newTotalWidth;
528
542
  this.totalHeight = newTotalHeight;
@@ -541,12 +555,13 @@ class GanttChart {
541
555
  }
542
556
  calculateAllTaskPositions() {
543
557
  this.taskPositions.clear();
544
- for (let i = 0; i < this.data.length; i++) {
558
+ let visibleRowIndex = 0;
559
+ for (let i = 0, len = this.data.length; i < len; i++) {
545
560
  const row = this.data[i];
546
561
  if (row.hide) {
547
562
  continue;
548
563
  }
549
- const y = i * this.config.rowHeight;
564
+ const y = visibleRowIndex * this.config.rowHeight;
550
565
  row.tasks.forEach((task) => {
551
566
  if (task.hide) {
552
567
  return;
@@ -590,9 +605,11 @@ class GanttChart {
590
605
  x_plan_width,
591
606
  x_actual_width,
592
607
  y: y + this.config.rowHeight * 0.5,
593
- row: i
608
+ row: visibleRowIndex
609
+ // Use visible row index instead of original index
594
610
  });
595
611
  });
612
+ visibleRowIndex++;
596
613
  }
597
614
  }
598
615
  getIterationStartDate(date) {
@@ -882,10 +899,17 @@ class GanttChart {
882
899
  ctx.font = '12px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
883
900
  ctx.textRendering = "optimizeSpeed";
884
901
  ctx.imageSmoothingEnabled = false;
902
+ let visibleRowIndex = 0;
885
903
  for (let i = 0; i < this.data.length; i++) {
886
904
  const row = this.data[i];
887
- const y = i * this.config.rowHeight;
888
- if (y + this.config.rowHeight < this.scrollTop || y > this.scrollTop + this.viewportHeight) continue;
905
+ if (row.hide) {
906
+ continue;
907
+ }
908
+ const y = visibleRowIndex * this.config.rowHeight;
909
+ if (y + this.config.rowHeight < this.scrollTop || y > this.scrollTop + this.viewportHeight) {
910
+ visibleRowIndex++;
911
+ continue;
912
+ }
889
913
  row.tasks.forEach((task) => {
890
914
  const pos = this.taskPositions.get(task.id);
891
915
  if (!pos) return;
@@ -894,14 +918,22 @@ class GanttChart {
894
918
  if (!isPlanVisible && !isActualVisible) return;
895
919
  this.drawTask(ctx, task, y, pos);
896
920
  });
921
+ visibleRowIndex++;
897
922
  }
898
923
  }
924
+ // In the drawGrid method
899
925
  drawGrid(ctx, startDate, endDate) {
900
926
  ctx.strokeStyle = "#e6e6e6";
901
927
  ctx.lineWidth = 1;
902
928
  ctx.beginPath();
903
929
  if (this.config.showRowLines) {
904
- for (let i = 0; i <= this.data.length; i++) {
930
+ let visibleRowCount = 0;
931
+ for (let i = 0; i < this.data.length; i++) {
932
+ if (!this.data[i].hide) {
933
+ visibleRowCount++;
934
+ }
935
+ }
936
+ for (let i = 0; i <= visibleRowCount; i++) {
905
937
  const y = i * this.config.rowHeight;
906
938
  if (y < this.scrollTop || y > this.scrollTop + this.viewportHeight) continue;
907
939
  ctx.moveTo(this.scrollLeft, y);
@@ -1046,10 +1078,21 @@ class GanttChart {
1046
1078
  const mouseY = e.clientY - rect.top;
1047
1079
  const chartX = mouseX + this.scrollLeft;
1048
1080
  const chartY = mouseY + this.scrollTop;
1049
- const rowIndex = Math.floor(chartY / this.config.rowHeight);
1081
+ const visibleRowIndex = Math.floor(chartY / this.config.rowHeight);
1082
+ let actualRowIndex = -1;
1083
+ let visibleRowCount = 0;
1084
+ for (let i = 0; i < this.data.length; i++) {
1085
+ if (!this.data[i].hide) {
1086
+ if (visibleRowCount === visibleRowIndex) {
1087
+ actualRowIndex = i;
1088
+ break;
1089
+ }
1090
+ visibleRowCount++;
1091
+ }
1092
+ }
1050
1093
  const date = this.xToDate(chartX);
1051
- if (rowIndex < 0 || rowIndex >= this.data.length) return this.handleMouseLeave();
1052
- const row = this.data[rowIndex];
1094
+ if (actualRowIndex < 0 || actualRowIndex >= this.data.length) return this.handleMouseLeave();
1095
+ const row = this.data[actualRowIndex];
1053
1096
  if (this.config.tooltipFormat) {
1054
1097
  const htmlStr = this.config.tooltipFormat(row, date, this.config);
1055
1098
  if (!htmlStr) {
package/dist/index.umd.js CHANGED
@@ -1,5 +1,5 @@
1
1
  /*!
2
- * gantt-canvas-chart v1.5.2
2
+ * gantt-canvas-chart v1.5.3
3
3
  * (c) 2025-present chandq
4
4
  * Released under the MIT License.
5
5
  */
@@ -157,7 +157,9 @@
157
157
  onDataLoad = null;
158
158
  scrollLoadTimer = null;
159
159
  constructor(rootContainer, data, config = {}) {
160
- if (rootContainer.querySelector(".__gantt-chart-container")) {
160
+ if (!rootContainer) {
161
+ throw new Error("Root container element is required");
162
+ } else if (rootContainer.querySelector(".__gantt-chart-container")) {
161
163
  throw new Error("GanttChart already exists in this container");
162
164
  }
163
165
  const container = document.createElement("div");
@@ -253,8 +255,18 @@
253
255
  }
254
256
  buildTaskMap() {
255
257
  this.taskMap.clear();
256
- this.data.forEach((row, rowIndex) => {
257
- row.tasks.forEach((task) => this.taskMap.set(task.id, { row: rowIndex, task }));
258
+ let visibleRowIndex = 0;
259
+ this.data.forEach((row) => {
260
+ row.tasks.forEach((task) => {
261
+ this.taskMap.set(task.id, {
262
+ row: row.hide ? -1 : visibleRowIndex,
263
+ // Use -1 for hidden rows
264
+ task
265
+ });
266
+ });
267
+ if (!row.hide) {
268
+ visibleRowIndex++;
269
+ }
258
270
  });
259
271
  }
260
272
  setupEvents() {
@@ -523,10 +535,12 @@
523
535
  end: this.xToDate(this.scrollLeft + this.viewportWidth + buffer)
524
536
  };
525
537
  }
538
+ // Update the updateDimensions method to calculate height based on visible rows
526
539
  updateDimensions() {
527
540
  const totalDays = DateUtils.diffDays(this.timelineStart, this.timelineEnd) + 1;
541
+ const visibleRowCount = this.data.filter((row) => !row.hide).length;
528
542
  const newTotalWidth = totalDays * this.pixelsPerDay;
529
- const newTotalHeight = this.data.length * this.config.rowHeight + this.config.headerHeight;
543
+ const newTotalHeight = visibleRowCount * this.config.rowHeight + this.config.headerHeight;
530
544
  if (this.totalWidth !== newTotalWidth || this.totalHeight !== newTotalHeight) {
531
545
  this.totalWidth = newTotalWidth;
532
546
  this.totalHeight = newTotalHeight;
@@ -545,12 +559,13 @@
545
559
  }
546
560
  calculateAllTaskPositions() {
547
561
  this.taskPositions.clear();
548
- for (let i = 0; i < this.data.length; i++) {
562
+ let visibleRowIndex = 0;
563
+ for (let i = 0, len = this.data.length; i < len; i++) {
549
564
  const row = this.data[i];
550
565
  if (row.hide) {
551
566
  continue;
552
567
  }
553
- const y = i * this.config.rowHeight;
568
+ const y = visibleRowIndex * this.config.rowHeight;
554
569
  row.tasks.forEach((task) => {
555
570
  if (task.hide) {
556
571
  return;
@@ -594,9 +609,11 @@
594
609
  x_plan_width,
595
610
  x_actual_width,
596
611
  y: y + this.config.rowHeight * 0.5,
597
- row: i
612
+ row: visibleRowIndex
613
+ // Use visible row index instead of original index
598
614
  });
599
615
  });
616
+ visibleRowIndex++;
600
617
  }
601
618
  }
602
619
  getIterationStartDate(date) {
@@ -886,10 +903,17 @@
886
903
  ctx.font = '12px -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, Helvetica, Arial, sans-serif';
887
904
  ctx.textRendering = "optimizeSpeed";
888
905
  ctx.imageSmoothingEnabled = false;
906
+ let visibleRowIndex = 0;
889
907
  for (let i = 0; i < this.data.length; i++) {
890
908
  const row = this.data[i];
891
- const y = i * this.config.rowHeight;
892
- if (y + this.config.rowHeight < this.scrollTop || y > this.scrollTop + this.viewportHeight) continue;
909
+ if (row.hide) {
910
+ continue;
911
+ }
912
+ const y = visibleRowIndex * this.config.rowHeight;
913
+ if (y + this.config.rowHeight < this.scrollTop || y > this.scrollTop + this.viewportHeight) {
914
+ visibleRowIndex++;
915
+ continue;
916
+ }
893
917
  row.tasks.forEach((task) => {
894
918
  const pos = this.taskPositions.get(task.id);
895
919
  if (!pos) return;
@@ -898,14 +922,22 @@
898
922
  if (!isPlanVisible && !isActualVisible) return;
899
923
  this.drawTask(ctx, task, y, pos);
900
924
  });
925
+ visibleRowIndex++;
901
926
  }
902
927
  }
928
+ // In the drawGrid method
903
929
  drawGrid(ctx, startDate, endDate) {
904
930
  ctx.strokeStyle = "#e6e6e6";
905
931
  ctx.lineWidth = 1;
906
932
  ctx.beginPath();
907
933
  if (this.config.showRowLines) {
908
- for (let i = 0; i <= this.data.length; i++) {
934
+ let visibleRowCount = 0;
935
+ for (let i = 0; i < this.data.length; i++) {
936
+ if (!this.data[i].hide) {
937
+ visibleRowCount++;
938
+ }
939
+ }
940
+ for (let i = 0; i <= visibleRowCount; i++) {
909
941
  const y = i * this.config.rowHeight;
910
942
  if (y < this.scrollTop || y > this.scrollTop + this.viewportHeight) continue;
911
943
  ctx.moveTo(this.scrollLeft, y);
@@ -1050,10 +1082,21 @@
1050
1082
  const mouseY = e.clientY - rect.top;
1051
1083
  const chartX = mouseX + this.scrollLeft;
1052
1084
  const chartY = mouseY + this.scrollTop;
1053
- const rowIndex = Math.floor(chartY / this.config.rowHeight);
1085
+ const visibleRowIndex = Math.floor(chartY / this.config.rowHeight);
1086
+ let actualRowIndex = -1;
1087
+ let visibleRowCount = 0;
1088
+ for (let i = 0; i < this.data.length; i++) {
1089
+ if (!this.data[i].hide) {
1090
+ if (visibleRowCount === visibleRowIndex) {
1091
+ actualRowIndex = i;
1092
+ break;
1093
+ }
1094
+ visibleRowCount++;
1095
+ }
1096
+ }
1054
1097
  const date = this.xToDate(chartX);
1055
- if (rowIndex < 0 || rowIndex >= this.data.length) return this.handleMouseLeave();
1056
- const row = this.data[rowIndex];
1098
+ if (actualRowIndex < 0 || actualRowIndex >= this.data.length) return this.handleMouseLeave();
1099
+ const row = this.data[actualRowIndex];
1057
1100
  if (this.config.tooltipFormat) {
1058
1101
  const htmlStr = this.config.tooltipFormat(row, date, this.config);
1059
1102
  if (!htmlStr) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gantt-canvas-chart",
3
- "version": "1.5.2",
3
+ "version": "1.5.3",
4
4
  "description": "High performance Gantt chart component based on Canvas, can be applied to any framework",
5
5
  "type": "module",
6
6
  "main": "dist/index.es.js",