apexgantt 3.1.0 → 3.2.0
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/README.md +39 -0
- package/apexgantt.es.min.js +153 -64
- package/apexgantt.min.js +2 -2
- package/demo/basic-gantt-large-range.html +1 -1
- package/demo/basic-gantt.html +1 -1
- package/demo/data-parsing.html +1 -1
- package/demo/gantt-with-annotations.html +1 -1
- package/demo/gantt-with-interactions.html +2 -1
- package/lib/gantt.d.ts +10 -0
- package/lib/models/Annotation.d.ts +5 -5
- package/lib/models/Options.d.ts +6 -1
- package/lib/models/Tasks.d.ts +9 -0
- package/lib/styles/Tasks.style.d.ts +1 -1
- package/lib/util/gantt-export.d.ts +1 -0
- package/lib/util/task.util.d.ts +7 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -67,6 +67,7 @@ The layout can be configured by either setting the properties in the table below
|
|
|
67
67
|
| barTextColor | `#FFFFFF` | Text color for timeline bar |
|
|
68
68
|
| cellBorderColor | `#eff0f0` | Border color for all table cells and timeline cells |
|
|
69
69
|
| cellBorderWidth | `1px` | Border width for all table cells and timeline cells |
|
|
70
|
+
| columnConfig | `undefined` | Custom column widths |
|
|
70
71
|
| enableToolbar | `false` | Enable/disable graph toolbar |
|
|
71
72
|
| enableResize | `true` | Enable/disable gantt sidebar resize |
|
|
72
73
|
| enableExport | `true` | Enable/disable gantt export options |
|
|
@@ -185,6 +186,44 @@ Each tasks should be in below format
|
|
|
185
186
|
];
|
|
186
187
|
```
|
|
187
188
|
|
|
189
|
+
## Column Configuration
|
|
190
|
+
|
|
191
|
+
Customize task table column widths:
|
|
192
|
+
|
|
193
|
+
```js
|
|
194
|
+
import {ColumnKey} from 'apexgantt';
|
|
195
|
+
|
|
196
|
+
const gantt = new ApexGantt(element, {
|
|
197
|
+
series: tasks,
|
|
198
|
+
columnConfig: [
|
|
199
|
+
{
|
|
200
|
+
key: ColumnKey.Name,
|
|
201
|
+
title: 'Task Name',
|
|
202
|
+
minWidth: '100px',
|
|
203
|
+
flexGrow: 3,
|
|
204
|
+
},
|
|
205
|
+
{
|
|
206
|
+
key: ColumnKey.StartTime,
|
|
207
|
+
title: 'Start',
|
|
208
|
+
minWidth: '100px',
|
|
209
|
+
flexGrow: 1.5,
|
|
210
|
+
},
|
|
211
|
+
{
|
|
212
|
+
key: ColumnKey.Duration,
|
|
213
|
+
title: 'Duration',
|
|
214
|
+
minWidth: '80px',
|
|
215
|
+
flexGrow: 1,
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
key: ColumnKey.Progress,
|
|
219
|
+
title: 'Progress',
|
|
220
|
+
minWidth: '80px',
|
|
221
|
+
flexGrow: 1,
|
|
222
|
+
},
|
|
223
|
+
],
|
|
224
|
+
});
|
|
225
|
+
```
|
|
226
|
+
|
|
188
227
|
## Data Parsing
|
|
189
228
|
|
|
190
229
|
Map your existing data structure to ApexGantt format without manual transformation.
|
package/apexgantt.es.min.js
CHANGED
|
@@ -5965,6 +5965,13 @@ const _Watermark = class _Watermark {
|
|
|
5965
5965
|
_Watermark.WATERMARK_CLASS = "apexgantt-watermark";
|
|
5966
5966
|
_Watermark.WATERMARK_TEXT = "Powered by apexcharts.com";
|
|
5967
5967
|
let Watermark = _Watermark;
|
|
5968
|
+
function getParentElement(element) {
|
|
5969
|
+
const rootNode = element.getRootNode();
|
|
5970
|
+
if (rootNode instanceof ShadowRoot) {
|
|
5971
|
+
return rootNode.host;
|
|
5972
|
+
}
|
|
5973
|
+
return element.parentElement;
|
|
5974
|
+
}
|
|
5968
5975
|
function getCumulativeTransform(element) {
|
|
5969
5976
|
let scaleX = 1;
|
|
5970
5977
|
let scaleY = 1;
|
|
@@ -5996,7 +6003,7 @@ function getCumulativeTransform(element) {
|
|
|
5996
6003
|
console.warn("Failed to parse transform matrix:", transform2, e);
|
|
5997
6004
|
}
|
|
5998
6005
|
}
|
|
5999
|
-
currentElement = currentElement
|
|
6006
|
+
currentElement = getParentElement(currentElement);
|
|
6000
6007
|
}
|
|
6001
6008
|
return { scaleX, scaleY, translateX, translateY };
|
|
6002
6009
|
}
|
|
@@ -13903,7 +13910,8 @@ const ColumnList = [
|
|
|
13903
13910
|
"name"
|
|
13904
13911
|
/* Name */
|
|
13905
13912
|
],
|
|
13906
|
-
|
|
13913
|
+
minWidth: "120px",
|
|
13914
|
+
flexGrow: 3
|
|
13907
13915
|
},
|
|
13908
13916
|
{
|
|
13909
13917
|
key: "startTime",
|
|
@@ -13911,7 +13919,8 @@ const ColumnList = [
|
|
|
13911
13919
|
"startTime"
|
|
13912
13920
|
/* StartTime */
|
|
13913
13921
|
],
|
|
13914
|
-
|
|
13922
|
+
minWidth: "70px",
|
|
13923
|
+
flexGrow: 1.5
|
|
13915
13924
|
},
|
|
13916
13925
|
{
|
|
13917
13926
|
key: "duration",
|
|
@@ -13919,7 +13928,8 @@ const ColumnList = [
|
|
|
13919
13928
|
"duration"
|
|
13920
13929
|
/* Duration */
|
|
13921
13930
|
],
|
|
13922
|
-
|
|
13931
|
+
minWidth: "50px",
|
|
13932
|
+
flexGrow: 1
|
|
13923
13933
|
},
|
|
13924
13934
|
{
|
|
13925
13935
|
key: "progress",
|
|
@@ -13927,9 +13937,17 @@ const ColumnList = [
|
|
|
13927
13937
|
"progress"
|
|
13928
13938
|
/* Progress */
|
|
13929
13939
|
],
|
|
13930
|
-
|
|
13940
|
+
minWidth: "50px",
|
|
13941
|
+
flexGrow: 1
|
|
13931
13942
|
}
|
|
13932
13943
|
];
|
|
13944
|
+
function generateGridTemplateColumns(columns) {
|
|
13945
|
+
return columns.map((col) => {
|
|
13946
|
+
const minWidth = col.minWidth || "30px";
|
|
13947
|
+
const flexGrow = col.flexGrow || 1;
|
|
13948
|
+
return `minmax(${minWidth}, ${flexGrow}fr)`;
|
|
13949
|
+
}).join(" ");
|
|
13950
|
+
}
|
|
13933
13951
|
function getTaskTextByColumn(task, columnKey, inputDateFormat) {
|
|
13934
13952
|
const taskColumnValue = task[columnKey];
|
|
13935
13953
|
if (columnKey === "startTime") {
|
|
@@ -14057,6 +14075,40 @@ class Tasks {
|
|
|
14057
14075
|
this.options = options;
|
|
14058
14076
|
this.chartContext = chartContext;
|
|
14059
14077
|
this.dataManager = dataManager;
|
|
14078
|
+
this.effectiveColumnList = this.mergeColumnConfig();
|
|
14079
|
+
this.injectDynamicColumnStyles();
|
|
14080
|
+
}
|
|
14081
|
+
/**
|
|
14082
|
+
* Merges user column config with defaults
|
|
14083
|
+
*/
|
|
14084
|
+
mergeColumnConfig() {
|
|
14085
|
+
if (!this.options.columnConfig || this.options.columnConfig.length === 0) {
|
|
14086
|
+
return ColumnList;
|
|
14087
|
+
}
|
|
14088
|
+
return ColumnList.map((defaultCol) => {
|
|
14089
|
+
var _a;
|
|
14090
|
+
const userCol = (_a = this.options.columnConfig) == null ? void 0 : _a.find((col) => col.key === defaultCol.key);
|
|
14091
|
+
return userCol ? { ...defaultCol, ...userCol } : defaultCol;
|
|
14092
|
+
});
|
|
14093
|
+
}
|
|
14094
|
+
/**
|
|
14095
|
+
* Dynamic CSS for column widths based on configuration
|
|
14096
|
+
*/
|
|
14097
|
+
injectDynamicColumnStyles() {
|
|
14098
|
+
const gridTemplate = generateGridTemplateColumns(this.effectiveColumnList);
|
|
14099
|
+
const chartInstanceId = this.chartContext.getInstanceId();
|
|
14100
|
+
const dynamicStyles = `
|
|
14101
|
+
.tasks-container .tasks-header[data-chart-instance="${chartInstanceId}"] .tasks-header-row {
|
|
14102
|
+
grid-template-columns: ${gridTemplate};
|
|
14103
|
+
}
|
|
14104
|
+
|
|
14105
|
+
.tasks-container .tasks-data-row[data-chart-instance="${chartInstanceId}"] {
|
|
14106
|
+
grid-template-columns: ${gridTemplate};
|
|
14107
|
+
}
|
|
14108
|
+
`;
|
|
14109
|
+
this.chartContext.injectStyles(dynamicStyles, `tasks-dynamic-columns-${chartInstanceId}`, {
|
|
14110
|
+
priority: "high"
|
|
14111
|
+
});
|
|
14060
14112
|
}
|
|
14061
14113
|
generateBody(tasks, reRender) {
|
|
14062
14114
|
const bodyContainer = createBox(this.chartContext, { className: "tasks-data-container" });
|
|
@@ -14069,19 +14121,13 @@ class Tasks {
|
|
|
14069
14121
|
const { headerBackground, rowHeight, fontColor } = this.options;
|
|
14070
14122
|
const chartInstanceId = this.chartContext.getInstanceId();
|
|
14071
14123
|
headerContainer.setAttribute("data-chart-instance", chartInstanceId);
|
|
14072
|
-
forEach(headerList, (header
|
|
14073
|
-
const columnDef = ColumnList[index];
|
|
14124
|
+
forEach(headerList, (header) => {
|
|
14074
14125
|
const headerCell = createBox(this.chartContext, {
|
|
14075
14126
|
className: "tasks-header-cell",
|
|
14076
14127
|
content: header
|
|
14077
14128
|
});
|
|
14078
14129
|
headerCell.style.height = `${rowHeight * 2}px`;
|
|
14079
14130
|
headerCell.style.color = fontColor;
|
|
14080
|
-
if (columnDef == null ? void 0 : columnDef.width) {
|
|
14081
|
-
headerCell.style.width = columnDef.width;
|
|
14082
|
-
headerCell.style.minWidth = columnDef.width;
|
|
14083
|
-
headerCell.style.flexBasis = columnDef.width;
|
|
14084
|
-
}
|
|
14085
14131
|
headerRow.append(headerCell);
|
|
14086
14132
|
});
|
|
14087
14133
|
headerContainer.append(headerRow);
|
|
@@ -14095,7 +14141,7 @@ class Tasks {
|
|
|
14095
14141
|
row.setAttribute("data-taskid", task.id);
|
|
14096
14142
|
row.setAttribute("data-chart-instance", chartInstanceId);
|
|
14097
14143
|
row.style.height = `${rowHeight}px`;
|
|
14098
|
-
forEach(
|
|
14144
|
+
forEach(this.effectiveColumnList, ({ key }) => {
|
|
14099
14145
|
const cell = createBox(this.chartContext, {
|
|
14100
14146
|
className: "tasks-data-cell",
|
|
14101
14147
|
content: getTaskTextByColumn(task, key, this.options.inputDateFormat)
|
|
@@ -14104,11 +14150,6 @@ class Tasks {
|
|
|
14104
14150
|
cell.setAttribute("data-chart-instance", chartInstanceId);
|
|
14105
14151
|
cell.style.height = `${rowHeight}px`;
|
|
14106
14152
|
cell.style.color = fontColor;
|
|
14107
|
-
if (width2) {
|
|
14108
|
-
cell.style.width = width2;
|
|
14109
|
-
cell.style.minWidth = width2;
|
|
14110
|
-
cell.style.flexBasis = width2;
|
|
14111
|
-
}
|
|
14112
14153
|
if (key === ColumnKey.Name) {
|
|
14113
14154
|
cell.style.paddingLeft = `${task.level * 15}px`;
|
|
14114
14155
|
cell.style.textAlign = "left";
|
|
@@ -14167,7 +14208,7 @@ class Tasks {
|
|
|
14167
14208
|
row.setAttribute("data-taskid", `empty-${index}`);
|
|
14168
14209
|
row.setAttribute("data-chart-instance", chartInstanceId);
|
|
14169
14210
|
row.style.height = `${rowHeight}px`;
|
|
14170
|
-
forEach(
|
|
14211
|
+
forEach(this.effectiveColumnList, ({ key }) => {
|
|
14171
14212
|
const cell = createBox(this.chartContext, {
|
|
14172
14213
|
className: "tasks-data-cell",
|
|
14173
14214
|
content: ""
|
|
@@ -14176,17 +14217,12 @@ class Tasks {
|
|
|
14176
14217
|
cell.setAttribute("data-chart-instance", chartInstanceId);
|
|
14177
14218
|
cell.style.height = `${rowHeight}px`;
|
|
14178
14219
|
cell.style.color = fontColor;
|
|
14179
|
-
if (width2) {
|
|
14180
|
-
cell.style.width = width2;
|
|
14181
|
-
cell.style.minWidth = width2;
|
|
14182
|
-
cell.style.flexBasis = width2;
|
|
14183
|
-
}
|
|
14184
14220
|
row.append(cell);
|
|
14185
14221
|
});
|
|
14186
14222
|
return row;
|
|
14187
14223
|
}
|
|
14188
14224
|
render(reRender) {
|
|
14189
|
-
const headerRow = this.generateHeader(
|
|
14225
|
+
const headerRow = this.generateHeader(this.effectiveColumnList.map((col) => col.title));
|
|
14190
14226
|
const dataRows = this.generateBody(this.dataManager.getFlatVisibleTasks(), reRender);
|
|
14191
14227
|
return [headerRow, dataRows];
|
|
14192
14228
|
}
|
|
@@ -15293,7 +15329,7 @@ const TableStyle = `
|
|
|
15293
15329
|
}
|
|
15294
15330
|
|
|
15295
15331
|
.tasks-header-row {
|
|
15296
|
-
display:
|
|
15332
|
+
display: grid;
|
|
15297
15333
|
width: 100%;
|
|
15298
15334
|
}
|
|
15299
15335
|
|
|
@@ -15308,7 +15344,6 @@ const TableStyle = `
|
|
|
15308
15344
|
border: var(--cell-border-width, 1px) solid var(--cell-border-color, #eff0f0);
|
|
15309
15345
|
color: var(--text-color, #000);
|
|
15310
15346
|
box-sizing: border-box;
|
|
15311
|
-
flex-shrink: 0;
|
|
15312
15347
|
font-weight: 600;
|
|
15313
15348
|
}
|
|
15314
15349
|
|
|
@@ -15325,7 +15360,7 @@ const TableStyle = `
|
|
|
15325
15360
|
}
|
|
15326
15361
|
|
|
15327
15362
|
.tasks-data-row {
|
|
15328
|
-
display:
|
|
15363
|
+
display: grid;
|
|
15329
15364
|
width: 100%;
|
|
15330
15365
|
border-bottom: var(--cell-border-width, 1px) solid var(--cell-border-color, #eff0f0);
|
|
15331
15366
|
box-sizing: border-box;
|
|
@@ -15343,7 +15378,6 @@ const TableStyle = `
|
|
|
15343
15378
|
border-right: var(--cell-border-width, 1px) solid var(--cell-border-color, #eff0f0);
|
|
15344
15379
|
color: var(--text-color, #000);
|
|
15345
15380
|
box-sizing: border-box;
|
|
15346
|
-
flex-shrink: 0;
|
|
15347
15381
|
}
|
|
15348
15382
|
|
|
15349
15383
|
.tasks-data-row .tasks-data-cell:first-child {
|
|
@@ -16240,7 +16274,7 @@ class SplitView {
|
|
|
16240
16274
|
|
|
16241
16275
|
.split-view-container .split-left-container {
|
|
16242
16276
|
flex-grow: 0 !important;
|
|
16243
|
-
flex-shrink:
|
|
16277
|
+
flex-shrink: 1 !important;
|
|
16244
16278
|
overflow: visible;
|
|
16245
16279
|
display: flex !important;
|
|
16246
16280
|
flex-direction: column;
|
|
@@ -16398,8 +16432,8 @@ class SplitView {
|
|
|
16398
16432
|
if (!containerRect)
|
|
16399
16433
|
return;
|
|
16400
16434
|
const newWidth = moveEvent.clientX - containerRect.left;
|
|
16401
|
-
const minWidth =
|
|
16402
|
-
const maxWidth = containerRect.width -
|
|
16435
|
+
const minWidth = 0;
|
|
16436
|
+
const maxWidth = containerRect.width - 50;
|
|
16403
16437
|
const clampedWidth = Math.max(minWidth, Math.min(maxWidth, newWidth));
|
|
16404
16438
|
this.leftContainer.style.flexBasis = `${clampedWidth}px`;
|
|
16405
16439
|
this.dispatchResizeEvent();
|
|
@@ -16428,25 +16462,29 @@ class SplitView {
|
|
|
16428
16462
|
switch (e.key) {
|
|
16429
16463
|
case "ArrowLeft":
|
|
16430
16464
|
e.preventDefault();
|
|
16431
|
-
newWidth = Math.max(
|
|
16465
|
+
newWidth = Math.max(0, currentWidth - step);
|
|
16432
16466
|
this.leftContainer.style.flexBasis = `${newWidth}px`;
|
|
16467
|
+
this.dispatchResizeEvent();
|
|
16433
16468
|
break;
|
|
16434
16469
|
case "ArrowRight":
|
|
16435
16470
|
e.preventDefault();
|
|
16436
16471
|
newWidth = currentWidth + step;
|
|
16437
16472
|
this.leftContainer.style.flexBasis = `${newWidth}px`;
|
|
16473
|
+
this.dispatchResizeEvent();
|
|
16438
16474
|
break;
|
|
16439
16475
|
case "Home":
|
|
16440
16476
|
e.preventDefault();
|
|
16441
|
-
this.leftContainer.style.flexBasis = "
|
|
16477
|
+
this.leftContainer.style.flexBasis = "0px";
|
|
16478
|
+
this.dispatchResizeEvent();
|
|
16442
16479
|
break;
|
|
16443
16480
|
case "End": {
|
|
16444
16481
|
e.preventDefault();
|
|
16445
16482
|
const container = this.splitBarContainer.parentElement;
|
|
16446
16483
|
if (container) {
|
|
16447
|
-
const maxWidth = container.clientWidth -
|
|
16484
|
+
const maxWidth = container.clientWidth - 50;
|
|
16448
16485
|
this.leftContainer.style.flexBasis = `${maxWidth}px`;
|
|
16449
16486
|
}
|
|
16487
|
+
this.dispatchResizeEvent();
|
|
16450
16488
|
break;
|
|
16451
16489
|
}
|
|
16452
16490
|
}
|
|
@@ -16714,6 +16752,9 @@ class ApexGantt extends BaseChart {
|
|
|
16714
16752
|
this.isSyncingScroll = false;
|
|
16715
16753
|
this.scrollbarResizeObserver = null;
|
|
16716
16754
|
this.splitBarResizeHandler = null;
|
|
16755
|
+
this.containerResizeObserver = null;
|
|
16756
|
+
this.lastKnownWidth = 0;
|
|
16757
|
+
this.resizeDebounceTimer = null;
|
|
16717
16758
|
const themeDefaults = getDefaultOptions(options == null ? void 0 : options.theme);
|
|
16718
16759
|
let processedSeries;
|
|
16719
16760
|
if (options == null ? void 0 : options.parsing) {
|
|
@@ -16951,18 +16992,13 @@ class ApexGantt extends BaseChart {
|
|
|
16951
16992
|
const existingDimensions = this.hasExplicitDimensions();
|
|
16952
16993
|
const normalizedHeight = this.normalizeDimension(height2);
|
|
16953
16994
|
const normalizedWidth = this.normalizeDimension(width2);
|
|
16995
|
+
this.element.style.width = normalizedWidth;
|
|
16954
16996
|
if (normalizedHeight === "100%" && existingDimensions.height) {
|
|
16955
16997
|
const computedHeight = window.getComputedStyle(this.element).height;
|
|
16956
16998
|
this.element.style.height = computedHeight;
|
|
16957
16999
|
} else {
|
|
16958
17000
|
this.element.style.height = normalizedHeight;
|
|
16959
17001
|
}
|
|
16960
|
-
if (normalizedWidth === "100%" && existingDimensions.width) {
|
|
16961
|
-
const computedWidth = window.getComputedStyle(this.element).width;
|
|
16962
|
-
this.element.style.width = computedWidth;
|
|
16963
|
-
} else {
|
|
16964
|
-
this.element.style.width = normalizedWidth;
|
|
16965
|
-
}
|
|
16966
17002
|
this.element.style.display = "flex";
|
|
16967
17003
|
this.element.style.flexDirection = "column";
|
|
16968
17004
|
this.element.style.boxSizing = "border-box";
|
|
@@ -16996,14 +17032,7 @@ class ApexGantt extends BaseChart {
|
|
|
16996
17032
|
this.setupDependencyArrowEvents();
|
|
16997
17033
|
this.renderDependencyArrows();
|
|
16998
17034
|
requestAnimationFrame(() => {
|
|
16999
|
-
this.
|
|
17000
|
-
this.compensateForScrollbar();
|
|
17001
|
-
this.updateHorizontalScrollbarContent();
|
|
17002
|
-
this.setupTimelineHorizontalScroll();
|
|
17003
|
-
this.positionHorizontalScrollbar();
|
|
17004
|
-
this.setupScrollbarResizeObserver();
|
|
17005
|
-
this.disableHeaderMousewheelScroll();
|
|
17006
|
-
this.fillEmptyRowsAfterRender();
|
|
17035
|
+
this.performAfterActions();
|
|
17007
17036
|
});
|
|
17008
17037
|
if (isReRender) {
|
|
17009
17038
|
requestAnimationFrame(() => {
|
|
@@ -17012,6 +17041,18 @@ class ApexGantt extends BaseChart {
|
|
|
17012
17041
|
}
|
|
17013
17042
|
return this.element;
|
|
17014
17043
|
}
|
|
17044
|
+
performAfterActions() {
|
|
17045
|
+
this.syncTasksColumnWidths();
|
|
17046
|
+
this.compensateForScrollbar();
|
|
17047
|
+
this.updateHorizontalScrollbarContent();
|
|
17048
|
+
this.setupTimelineHorizontalScroll();
|
|
17049
|
+
this.positionHorizontalScrollbar();
|
|
17050
|
+
this.setupContainerResizeObserver();
|
|
17051
|
+
this.setupScrollbarResizeObserver();
|
|
17052
|
+
this.setupRowBackgroundColors();
|
|
17053
|
+
this.disableHeaderMousewheelScroll();
|
|
17054
|
+
this.fillEmptyRowsAfterRender();
|
|
17055
|
+
}
|
|
17015
17056
|
/**
|
|
17016
17057
|
* Setup proper positioning for chart container to support dialogs
|
|
17017
17058
|
*/
|
|
@@ -17350,15 +17391,7 @@ class ApexGantt extends BaseChart {
|
|
|
17350
17391
|
}
|
|
17351
17392
|
}
|
|
17352
17393
|
requestAnimationFrame(() => {
|
|
17353
|
-
this.
|
|
17354
|
-
this.compensateForScrollbar();
|
|
17355
|
-
this.updateHorizontalScrollbarContent();
|
|
17356
|
-
this.setupTimelineHorizontalScroll();
|
|
17357
|
-
this.positionHorizontalScrollbar();
|
|
17358
|
-
this.setupScrollbarResizeObserver();
|
|
17359
|
-
this.setupRowBackgroundColors();
|
|
17360
|
-
this.disableHeaderMousewheelScroll();
|
|
17361
|
-
this.fillEmptyRowsAfterRender();
|
|
17394
|
+
this.performAfterActions();
|
|
17362
17395
|
});
|
|
17363
17396
|
}
|
|
17364
17397
|
updateToolbarAfterZoom() {
|
|
@@ -17635,7 +17668,7 @@ class ApexGantt extends BaseChart {
|
|
|
17635
17668
|
row.setAttribute("data-taskid", `empty-${index}`);
|
|
17636
17669
|
row.setAttribute("data-chart-instance", chartInstanceId);
|
|
17637
17670
|
row.style.height = `${rowHeight}px`;
|
|
17638
|
-
ColumnList.forEach(({ key
|
|
17671
|
+
ColumnList.forEach(({ key }) => {
|
|
17639
17672
|
const cell = createBox(this.chartContext, {
|
|
17640
17673
|
className: "tasks-data-cell",
|
|
17641
17674
|
content: ""
|
|
@@ -17644,11 +17677,6 @@ class ApexGantt extends BaseChart {
|
|
|
17644
17677
|
cell.setAttribute("data-chart-instance", chartInstanceId);
|
|
17645
17678
|
cell.style.height = `${rowHeight}px`;
|
|
17646
17679
|
cell.style.color = fontColor;
|
|
17647
|
-
if (width2) {
|
|
17648
|
-
cell.style.width = width2;
|
|
17649
|
-
cell.style.minWidth = width2;
|
|
17650
|
-
cell.style.flexBasis = width2;
|
|
17651
|
-
}
|
|
17652
17680
|
row.appendChild(cell);
|
|
17653
17681
|
});
|
|
17654
17682
|
return row;
|
|
@@ -17756,8 +17784,69 @@ class ApexGantt extends BaseChart {
|
|
|
17756
17784
|
}
|
|
17757
17785
|
return value;
|
|
17758
17786
|
}
|
|
17787
|
+
/**
|
|
17788
|
+
* resize observer for container to handle responsive width changes
|
|
17789
|
+
*/
|
|
17790
|
+
setupContainerResizeObserver() {
|
|
17791
|
+
if (!this.element) {
|
|
17792
|
+
return;
|
|
17793
|
+
}
|
|
17794
|
+
if (this.containerResizeObserver) {
|
|
17795
|
+
this.containerResizeObserver.disconnect();
|
|
17796
|
+
}
|
|
17797
|
+
const normalizedWidth = this.normalizeDimension(this.options.width);
|
|
17798
|
+
const isPercentageWidth = typeof normalizedWidth === "string" && normalizedWidth.includes("%");
|
|
17799
|
+
if (!isPercentageWidth) {
|
|
17800
|
+
return;
|
|
17801
|
+
}
|
|
17802
|
+
this.lastKnownWidth = this.element.offsetWidth;
|
|
17803
|
+
this.containerResizeObserver = new ResizeObserver((entries) => {
|
|
17804
|
+
for (const entry of entries) {
|
|
17805
|
+
const newWidth = entry.contentRect.width;
|
|
17806
|
+
if (Math.abs(newWidth - this.lastKnownWidth) > 1) {
|
|
17807
|
+
this.lastKnownWidth = newWidth;
|
|
17808
|
+
this.handleContainerResize();
|
|
17809
|
+
}
|
|
17810
|
+
}
|
|
17811
|
+
});
|
|
17812
|
+
this.containerResizeObserver.observe(this.element);
|
|
17813
|
+
}
|
|
17814
|
+
handleContainerResize() {
|
|
17815
|
+
if (this.resizeDebounceTimer !== null) {
|
|
17816
|
+
window.clearTimeout(this.resizeDebounceTimer);
|
|
17817
|
+
}
|
|
17818
|
+
this.resizeDebounceTimer = window.setTimeout(() => {
|
|
17819
|
+
this.performResize();
|
|
17820
|
+
this.resizeDebounceTimer = null;
|
|
17821
|
+
}, 150);
|
|
17822
|
+
}
|
|
17823
|
+
performResize() {
|
|
17824
|
+
if (!this.element || this.isDestroyed()) {
|
|
17825
|
+
return;
|
|
17826
|
+
}
|
|
17827
|
+
const normalizedWidth = this.normalizeDimension(this.options.width);
|
|
17828
|
+
if (typeof normalizedWidth === "string" && normalizedWidth.includes("%")) {
|
|
17829
|
+
const computedWidth = window.getComputedStyle(this.element.parentElement || this.element).width;
|
|
17830
|
+
const currentElementWidth = window.getComputedStyle(this.element).width;
|
|
17831
|
+
if (computedWidth !== currentElementWidth) {
|
|
17832
|
+
requestAnimationFrame(() => {
|
|
17833
|
+
this.positionHorizontalScrollbar();
|
|
17834
|
+
this.updateHorizontalScrollbarContent();
|
|
17835
|
+
this.syncTasksColumnWidths();
|
|
17836
|
+
});
|
|
17837
|
+
}
|
|
17838
|
+
}
|
|
17839
|
+
}
|
|
17759
17840
|
destroy() {
|
|
17760
17841
|
try {
|
|
17842
|
+
if (this.containerResizeObserver) {
|
|
17843
|
+
this.containerResizeObserver.disconnect();
|
|
17844
|
+
this.containerResizeObserver = null;
|
|
17845
|
+
}
|
|
17846
|
+
if (this.resizeDebounceTimer !== null) {
|
|
17847
|
+
window.clearTimeout(this.resizeDebounceTimer);
|
|
17848
|
+
this.resizeDebounceTimer = null;
|
|
17849
|
+
}
|
|
17761
17850
|
if (this.zoomHandler) {
|
|
17762
17851
|
const chartInstanceId = this.getInstanceId();
|
|
17763
17852
|
const timelineElement = this.chartContext.querySelector(
|