vxe-gantt 4.7.3 → 4.8.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/dist/all.esm.js +341 -51
- package/dist/style.css +1 -1
- package/dist/style.min.css +1 -1
- package/es/gantt/src/gantt-chart.js +5 -2
- package/es/gantt/src/gantt-view.js +224 -6
- package/es/gantt/src/gantt.js +67 -4
- package/es/gantt/style.css +23 -13
- package/es/gantt/style.min.css +1 -1
- package/es/style.css +1 -1
- package/es/style.min.css +1 -1
- package/es/ui/index.js +8 -1
- package/es/ui/src/log.js +1 -1
- package/es/vxe-gantt/style.css +23 -13
- package/es/vxe-gantt/style.min.css +1 -1
- package/lib/gantt/src/gantt-chart.js +8 -1
- package/lib/gantt/src/gantt-chart.min.js +1 -1
- package/lib/gantt/src/gantt-view.js +233 -8
- package/lib/gantt/src/gantt-view.min.js +1 -1
- package/lib/gantt/src/gantt.js +74 -3
- package/lib/gantt/src/gantt.min.js +1 -1
- package/lib/gantt/style/style.css +23 -13
- package/lib/gantt/style/style.min.css +1 -1
- package/lib/index.umd.js +1191 -121
- package/lib/index.umd.min.js +1 -1
- package/lib/style.css +1 -1
- package/lib/style.min.css +1 -1
- package/lib/ui/index.js +8 -1
- package/lib/ui/index.min.js +1 -1
- package/lib/ui/src/log.js +1 -1
- package/lib/ui/src/log.min.js +1 -1
- package/lib/vxe-gantt/style/style.css +23 -13
- package/lib/vxe-gantt/style/style.min.css +1 -1
- package/package.json +3 -3
- package/packages/gantt/src/gantt-chart.ts +5 -2
- package/packages/gantt/src/gantt-view.ts +261 -8
- package/packages/gantt/src/gantt.ts +70 -3
- package/packages/gantt/src/util.ts +1 -1
- package/packages/ui/index.ts +7 -0
- package/styles/components/gantt-module/gantt-chart.scss +12 -0
- package/styles/components/gantt.scss +17 -13
- package/styles/theme/base.scss +2 -0
package/dist/all.esm.js
CHANGED
|
@@ -6,7 +6,7 @@ import DomZIndex from 'dom-zindex';
|
|
|
6
6
|
import { VxeTable } from 'vxe-table';
|
|
7
7
|
|
|
8
8
|
const { setConfig: setConfig$1, setIcon } = VxeUI;
|
|
9
|
-
VxeUI.ganttVersion = "4.7.
|
|
9
|
+
VxeUI.ganttVersion = "4.7.4";
|
|
10
10
|
const ymdFormat = 'yyyy-MM-dd';
|
|
11
11
|
const ymdhmsFormat = 'yyyy-MM-dd HH:mm:ss';
|
|
12
12
|
setConfig$1({
|
|
@@ -102,6 +102,13 @@ setConfig$1({
|
|
|
102
102
|
taskBarSubviewConfig: {
|
|
103
103
|
// showOverview: false
|
|
104
104
|
},
|
|
105
|
+
taskBarMoveConfig: {
|
|
106
|
+
isLimitByLink: true
|
|
107
|
+
},
|
|
108
|
+
taskBarResizeConfig: {
|
|
109
|
+
minWidthSize: 0.5,
|
|
110
|
+
isLimitByLink: true
|
|
111
|
+
},
|
|
105
112
|
taskBarMoveTooltipConfig: {
|
|
106
113
|
enterable: true,
|
|
107
114
|
enterDelay: 0
|
|
@@ -123,7 +130,7 @@ setIcon({
|
|
|
123
130
|
});
|
|
124
131
|
|
|
125
132
|
const { log } = VxeUI;
|
|
126
|
-
const ganttVersion = `gantt v${"4.7.
|
|
133
|
+
const ganttVersion = `gantt v${"4.7.4"}`;
|
|
127
134
|
function createComponentLog(name) {
|
|
128
135
|
const uiVersion = VxeUI.uiVersion ? `ui v${VxeUI.uiVersion}` : '';
|
|
129
136
|
const tableVersion = VxeUI.tableVersion ? `table v${VxeUI.tableVersion}` : '';
|
|
@@ -446,6 +453,43 @@ function getTaskType(type) {
|
|
|
446
453
|
return taskTypeMaps[type] ? type : 'default';
|
|
447
454
|
}
|
|
448
455
|
|
|
456
|
+
/**
|
|
457
|
+
* 依赖线枚举类型
|
|
458
|
+
*/
|
|
459
|
+
var VxeGanttDependencyType;
|
|
460
|
+
(function (VxeGanttDependencyType) {
|
|
461
|
+
/**
|
|
462
|
+
* 结束后才开始,表示一个任务必须在另一个任务开始之前完成
|
|
463
|
+
*/
|
|
464
|
+
VxeGanttDependencyType[VxeGanttDependencyType["FinishToStart"] = 0] = "FinishToStart";
|
|
465
|
+
/**
|
|
466
|
+
* 开始到结束,表示从某个过程的开始到结束的整个过程
|
|
467
|
+
*/
|
|
468
|
+
VxeGanttDependencyType[VxeGanttDependencyType["StartToFinish"] = 1] = "StartToFinish";
|
|
469
|
+
/**
|
|
470
|
+
* 开始后才开始,表示一个活动结束了,另一个活动才能开始,它们之间按先后顺序进行
|
|
471
|
+
*/
|
|
472
|
+
VxeGanttDependencyType[VxeGanttDependencyType["StartToStart"] = 2] = "StartToStart";
|
|
473
|
+
/**
|
|
474
|
+
* 完成到完成,表示一个任务必须在另一个任务完成之后才能完成
|
|
475
|
+
*/
|
|
476
|
+
VxeGanttDependencyType[VxeGanttDependencyType["FinishToFinish"] = 3] = "FinishToFinish";
|
|
477
|
+
})(VxeGanttDependencyType || (VxeGanttDependencyType = {}));
|
|
478
|
+
/**
|
|
479
|
+
* 任务渲染类型
|
|
480
|
+
*/
|
|
481
|
+
var VxeGanttTaskType;
|
|
482
|
+
(function (VxeGanttTaskType) {
|
|
483
|
+
/**
|
|
484
|
+
* 里程碑类型,该类型节点不需要结束日期
|
|
485
|
+
*/
|
|
486
|
+
VxeGanttTaskType["Milestone"] = "milestone";
|
|
487
|
+
/**
|
|
488
|
+
* 子视图类型,该类型会将子任务渲染到一行,无需开始日期和结束日期
|
|
489
|
+
*/
|
|
490
|
+
VxeGanttTaskType["Subview"] = "subview";
|
|
491
|
+
})(VxeGanttTaskType || (VxeGanttTaskType = {}));
|
|
492
|
+
|
|
449
493
|
const { getI18n: getI18n$1 } = VxeUI;
|
|
450
494
|
const sourceType$4 = 'gantt';
|
|
451
495
|
const viewType$3 = 'header';
|
|
@@ -633,7 +677,8 @@ var GanttViewChartComponent = defineVxeComponent({
|
|
|
633
677
|
const taskBarSlot = ganttSlots.taskBar || ganttSlots['task-bar'];
|
|
634
678
|
const taskBarOverviewSlot = ganttSlots.taskBarOverview || ganttSlots['task-bar-overview'];
|
|
635
679
|
const { treeConfig, taskBarMilestoneConfig, taskBarSubviewConfig } = ganttProps;
|
|
636
|
-
const { activeLink, activeBarRowid } = ganttReactData;
|
|
680
|
+
const { activeLink, activeBarRowid, criticalPathFlag } = ganttReactData;
|
|
681
|
+
const { criticalRowMaps } = ganttInternalData;
|
|
637
682
|
const titleField = computeTitleField.value;
|
|
638
683
|
const progressField = computeProgressField.value;
|
|
639
684
|
const typeField = computeTypeField.value;
|
|
@@ -652,7 +697,7 @@ var GanttViewChartComponent = defineVxeComponent({
|
|
|
652
697
|
rowIndex,
|
|
653
698
|
_rowIndex
|
|
654
699
|
};
|
|
655
|
-
const { showProgress, showContent, contentMethod, barStyle, moveable, showTooltip } = taskBarOpts;
|
|
700
|
+
const { showProgress, showCriticalPath, showContent, contentMethod, barStyle, moveable, showTooltip } = taskBarOpts;
|
|
656
701
|
const isBarRowStyle = XEUtils.isFunction(barStyle);
|
|
657
702
|
const barStyObj = (barStyle ? (isBarRowStyle ? barStyle(barParams) || undefined : barStyle) : {}) || {};
|
|
658
703
|
const barRound = barStyObj.round;
|
|
@@ -811,6 +856,7 @@ var GanttViewChartComponent = defineVxeComponent({
|
|
|
811
856
|
rowid: childRowid,
|
|
812
857
|
class: ['vxe-gantt-view--chart-subview-row', `is--${childRenderTaskType}`, {
|
|
813
858
|
'is--progress': showProgress,
|
|
859
|
+
'is--critical': showCriticalPath && criticalPathFlag && criticalRowMaps.has(childRowid),
|
|
814
860
|
'is--round': childRound,
|
|
815
861
|
'is--move': moveable,
|
|
816
862
|
'row--pending': !!pendingRowFlag && !!pendingRowMaps[childRowid]
|
|
@@ -904,6 +950,7 @@ var GanttViewChartComponent = defineVxeComponent({
|
|
|
904
950
|
rowid,
|
|
905
951
|
class: ['vxe-gantt-view--chart-row', `is--${renderTaskType}`, {
|
|
906
952
|
'is--progress': showProgress,
|
|
953
|
+
'is--critical': showCriticalPath && criticalPathFlag && criticalRowMaps.has(rowid),
|
|
907
954
|
'row--pending': !!pendingRowFlag && !!pendingRowMaps[rowid],
|
|
908
955
|
'is--round': barRound,
|
|
909
956
|
'is--move': moveable
|
|
@@ -1345,11 +1392,15 @@ var GanttViewFooterComponent = defineVxeComponent({
|
|
|
1345
1392
|
});
|
|
1346
1393
|
|
|
1347
1394
|
const { globalEvents: globalEvents$1 } = VxeUI;
|
|
1395
|
+
const { FinishToStart, StartToFinish, StartToStart, FinishToFinish } = VxeGanttDependencyType;
|
|
1348
1396
|
const sourceType = 'gantt';
|
|
1349
1397
|
const secondMs = 1000;
|
|
1350
1398
|
const minuteMs = 1000 * 60;
|
|
1351
1399
|
const hourMs = 1000 * 60 * 60;
|
|
1352
1400
|
const dayMs = hourMs * 24;
|
|
1401
|
+
function getTaskLinkKey(from, to, type) {
|
|
1402
|
+
return from + '_' + to + '_' + (type || 0);
|
|
1403
|
+
}
|
|
1353
1404
|
function createInternalData$1() {
|
|
1354
1405
|
return {
|
|
1355
1406
|
xeTable: null,
|
|
@@ -1413,8 +1464,10 @@ var GanttViewComponent = defineVxeComponent({
|
|
|
1413
1464
|
setup(props, context) {
|
|
1414
1465
|
const xID = XEUtils.uniqueId();
|
|
1415
1466
|
const $xeGantt = inject('$xeGantt', {});
|
|
1416
|
-
const
|
|
1417
|
-
const
|
|
1467
|
+
const ganttProps = $xeGantt.props;
|
|
1468
|
+
const ganttReactData = $xeGantt.reactData;
|
|
1469
|
+
const ganttInternalData = $xeGantt.internalData;
|
|
1470
|
+
const { computeDateFormat, computeTaskBarOpts, computeTaskViewOpts, computeStartField, computeEndField, computeTypeField, computeScrollbarOpts, computeScrollbarXToTop, computeScrollbarYToLeft, computeScaleUnit, computeWeekScale, computeMinScale, computeTaskNowLineOpts, computeScaleStep } = $xeGantt.getComputeMaps();
|
|
1418
1471
|
const refElem = ref();
|
|
1419
1472
|
const refScrollXVirtualElem = ref();
|
|
1420
1473
|
const refScrollYVirtualElem = ref();
|
|
@@ -1539,7 +1592,6 @@ var GanttViewComponent = defineVxeComponent({
|
|
|
1539
1592
|
return dateList;
|
|
1540
1593
|
});
|
|
1541
1594
|
const computeNowLineLeft = computed(() => {
|
|
1542
|
-
const ganttReactData = $xeGantt.reactData;
|
|
1543
1595
|
const { minViewDate, maxViewDate, viewCellWidth } = reactData;
|
|
1544
1596
|
const { visibleColumn, todayDateMaps } = internalData;
|
|
1545
1597
|
const minScale = computeMinScale.value;
|
|
@@ -1600,7 +1652,6 @@ var GanttViewComponent = defineVxeComponent({
|
|
|
1600
1652
|
return XEUtils.toStringDate(dateValue, dateFormat);
|
|
1601
1653
|
};
|
|
1602
1654
|
const updateTodayData = () => {
|
|
1603
|
-
const ganttReactData = $xeGantt.reactData;
|
|
1604
1655
|
const { taskScaleList } = ganttReactData;
|
|
1605
1656
|
const minScale = computeMinScale.value;
|
|
1606
1657
|
if (minScale) {
|
|
@@ -1632,7 +1683,6 @@ var GanttViewComponent = defineVxeComponent({
|
|
|
1632
1683
|
}
|
|
1633
1684
|
};
|
|
1634
1685
|
const handleColumnHeader = () => {
|
|
1635
|
-
const ganttReactData = $xeGantt.reactData;
|
|
1636
1686
|
const { taskScaleList } = ganttReactData;
|
|
1637
1687
|
const scaleUnit = computeScaleUnit.value;
|
|
1638
1688
|
const minScale = computeMinScale.value;
|
|
@@ -2307,7 +2357,7 @@ var GanttViewComponent = defineVxeComponent({
|
|
|
2307
2357
|
handleTableColumn();
|
|
2308
2358
|
};
|
|
2309
2359
|
const handleUpdateData = () => {
|
|
2310
|
-
const
|
|
2360
|
+
const { linkList } = ganttReactData;
|
|
2311
2361
|
const { treeConfig } = ganttProps;
|
|
2312
2362
|
const { scrollXStore } = internalData;
|
|
2313
2363
|
const $xeTable = internalData.xeTable;
|
|
@@ -2315,6 +2365,7 @@ var GanttViewComponent = defineVxeComponent({
|
|
|
2315
2365
|
const edMaps = {};
|
|
2316
2366
|
let minDate = null;
|
|
2317
2367
|
let maxDate = null;
|
|
2368
|
+
const allList = [];
|
|
2318
2369
|
if ($xeTable) {
|
|
2319
2370
|
const startField = computeStartField.value;
|
|
2320
2371
|
const endField = computeEndField.value;
|
|
@@ -2351,6 +2402,7 @@ var GanttViewComponent = defineVxeComponent({
|
|
|
2351
2402
|
maxDate = endDate;
|
|
2352
2403
|
}
|
|
2353
2404
|
}
|
|
2405
|
+
allList.push(row);
|
|
2354
2406
|
};
|
|
2355
2407
|
if (isRowGroupStatus) {
|
|
2356
2408
|
// 行分组
|
|
@@ -2374,7 +2426,219 @@ var GanttViewComponent = defineVxeComponent({
|
|
|
2374
2426
|
internalData.startMaps = sdMaps;
|
|
2375
2427
|
internalData.endMaps = edMaps;
|
|
2376
2428
|
handleParseColumn();
|
|
2429
|
+
handleCriticalPath(allList, linkList);
|
|
2377
2430
|
};
|
|
2431
|
+
/**
|
|
2432
|
+
* 正向:后置 ES 的下连接线
|
|
2433
|
+
*/
|
|
2434
|
+
function forwardCriticalPathLowerBound(linkType, predES, predEF, duration) {
|
|
2435
|
+
switch (linkType) {
|
|
2436
|
+
case FinishToStart:
|
|
2437
|
+
return predEF;
|
|
2438
|
+
case StartToFinish:
|
|
2439
|
+
return predES - duration;
|
|
2440
|
+
case StartToStart:
|
|
2441
|
+
return predES;
|
|
2442
|
+
case FinishToFinish:
|
|
2443
|
+
return predEF - duration;
|
|
2444
|
+
default:
|
|
2445
|
+
return 0;
|
|
2446
|
+
}
|
|
2447
|
+
}
|
|
2448
|
+
/**
|
|
2449
|
+
* 反向:前置 LF 的上连接线
|
|
2450
|
+
*/
|
|
2451
|
+
function backwardCriticalPathUpperBound(linkType, succLS, succLF, duration) {
|
|
2452
|
+
switch (linkType) {
|
|
2453
|
+
case FinishToStart:
|
|
2454
|
+
return succLS;
|
|
2455
|
+
case StartToFinish:
|
|
2456
|
+
return succLF + duration;
|
|
2457
|
+
case StartToStart:
|
|
2458
|
+
return succLS + duration;
|
|
2459
|
+
case FinishToFinish:
|
|
2460
|
+
return succLF;
|
|
2461
|
+
default:
|
|
2462
|
+
return -1;
|
|
2463
|
+
}
|
|
2464
|
+
}
|
|
2465
|
+
/**
|
|
2466
|
+
* 关键边:两端都关键时,约束是否连接
|
|
2467
|
+
*/
|
|
2468
|
+
function isCriticalPathLinkTight(linkType, fromES, fromEF, toES, toEF, tolerance) {
|
|
2469
|
+
switch (linkType) {
|
|
2470
|
+
case FinishToStart:
|
|
2471
|
+
return Math.abs(fromEF - toES) < tolerance;
|
|
2472
|
+
case StartToFinish:
|
|
2473
|
+
return Math.abs(fromES - toEF) < tolerance;
|
|
2474
|
+
case StartToStart:
|
|
2475
|
+
return Math.abs(fromES - toES) < tolerance;
|
|
2476
|
+
case FinishToFinish:
|
|
2477
|
+
return Math.abs(fromEF - toEF) < tolerance;
|
|
2478
|
+
default:
|
|
2479
|
+
return false;
|
|
2480
|
+
}
|
|
2481
|
+
}
|
|
2482
|
+
function handleCriticalPath(data, links) {
|
|
2483
|
+
const taskBarOpts = computeTaskBarOpts.value;
|
|
2484
|
+
const $xeTable = internalData.xeTable;
|
|
2485
|
+
const criticalRowList = [];
|
|
2486
|
+
const criticalRowMaps = new Map();
|
|
2487
|
+
const criticalLinkKeyMaps = new Map();
|
|
2488
|
+
ganttInternalData.criticalRowList = criticalRowList;
|
|
2489
|
+
ganttInternalData.criticalRowMaps = criticalRowMaps;
|
|
2490
|
+
ganttInternalData.criticalLinkKeyMaps = criticalLinkKeyMaps;
|
|
2491
|
+
if (!taskBarOpts.showCriticalPath || !links.length || !data.length || !$xeTable) {
|
|
2492
|
+
if (ganttReactData.criticalRowIds.length || ganttReactData.criticalLinks.length) {
|
|
2493
|
+
ganttReactData.criticalPathFlag++;
|
|
2494
|
+
}
|
|
2495
|
+
ganttReactData.criticalLinks = [];
|
|
2496
|
+
ganttReactData.criticalRowIds = [];
|
|
2497
|
+
return;
|
|
2498
|
+
}
|
|
2499
|
+
const { chartMaps } = internalData;
|
|
2500
|
+
const tolerance = 1e-6;
|
|
2501
|
+
const nodeMap = new Map();
|
|
2502
|
+
for (const row of data) {
|
|
2503
|
+
const rowid = $xeTable.getRowid(row);
|
|
2504
|
+
const chartRest = chartMaps[rowid];
|
|
2505
|
+
nodeMap.set(rowid, {
|
|
2506
|
+
row,
|
|
2507
|
+
rowid: rowid,
|
|
2508
|
+
duration: chartRest ? chartRest.oWidthSize : 0,
|
|
2509
|
+
incoming: [],
|
|
2510
|
+
outgoing: [],
|
|
2511
|
+
indeg: 0,
|
|
2512
|
+
ES: 0,
|
|
2513
|
+
EF: 0,
|
|
2514
|
+
LS: 0,
|
|
2515
|
+
LF: 0
|
|
2516
|
+
});
|
|
2517
|
+
}
|
|
2518
|
+
// 边界
|
|
2519
|
+
const linkList = [];
|
|
2520
|
+
for (const link of links) {
|
|
2521
|
+
const fromKey = '' + link.from;
|
|
2522
|
+
const toKey = '' + link.to;
|
|
2523
|
+
if (!nodeMap.has(fromKey) || !nodeMap.has(toKey) || fromKey === toKey) {
|
|
2524
|
+
continue;
|
|
2525
|
+
}
|
|
2526
|
+
const lkItemitem = {
|
|
2527
|
+
from: link.from,
|
|
2528
|
+
to: link.to,
|
|
2529
|
+
type: XEUtils.toNumber(link.type) || 0,
|
|
2530
|
+
raw: link
|
|
2531
|
+
};
|
|
2532
|
+
linkList.push(lkItemitem);
|
|
2533
|
+
const toObjItem = nodeMap.get('' + link.to);
|
|
2534
|
+
const fromObjItem = nodeMap.get('' + link.from);
|
|
2535
|
+
if (fromObjItem) {
|
|
2536
|
+
fromObjItem.outgoing.push(lkItemitem);
|
|
2537
|
+
}
|
|
2538
|
+
if (toObjItem) {
|
|
2539
|
+
toObjItem.incoming.push(lkItemitem);
|
|
2540
|
+
toObjItem.indeg++;
|
|
2541
|
+
}
|
|
2542
|
+
}
|
|
2543
|
+
// 拓扑排序 + 环检测
|
|
2544
|
+
const queueList = [];
|
|
2545
|
+
nodeMap.forEach(nodeitem => {
|
|
2546
|
+
if (nodeitem.indeg === 0) {
|
|
2547
|
+
queueList.push(nodeitem);
|
|
2548
|
+
}
|
|
2549
|
+
});
|
|
2550
|
+
const orderList = [];
|
|
2551
|
+
for (let head = 0; head < queueList.length; head++) {
|
|
2552
|
+
const node = queueList[head];
|
|
2553
|
+
orderList.push(node);
|
|
2554
|
+
for (const lkItemitem of node.outgoing) {
|
|
2555
|
+
const toObjItem = nodeMap.get('' + lkItemitem.to);
|
|
2556
|
+
if (toObjItem) {
|
|
2557
|
+
const nextDeg = toObjItem.indeg - 1;
|
|
2558
|
+
toObjItem.indeg = nextDeg;
|
|
2559
|
+
if (nextDeg === 0) {
|
|
2560
|
+
queueList.push(nodeMap.get('' + lkItemitem.to));
|
|
2561
|
+
}
|
|
2562
|
+
}
|
|
2563
|
+
}
|
|
2564
|
+
}
|
|
2565
|
+
if (orderList.length !== nodeMap.size) {
|
|
2566
|
+
// 异常数据,依赖图中存在环
|
|
2567
|
+
if (ganttReactData.criticalRowIds.length || ganttReactData.criticalLinks.length) {
|
|
2568
|
+
ganttReactData.criticalPathFlag++;
|
|
2569
|
+
}
|
|
2570
|
+
ganttReactData.criticalLinks = [];
|
|
2571
|
+
ganttReactData.criticalRowIds = [];
|
|
2572
|
+
return;
|
|
2573
|
+
}
|
|
2574
|
+
// 正向:ES / EF
|
|
2575
|
+
let criticalDuration = 0;
|
|
2576
|
+
for (const node of orderList) {
|
|
2577
|
+
let earliestStart = 0;
|
|
2578
|
+
for (const lkItem of node.incoming) {
|
|
2579
|
+
const fromObjItem = nodeMap.get('' + lkItem.from);
|
|
2580
|
+
if (fromObjItem) {
|
|
2581
|
+
const need = forwardCriticalPathLowerBound(lkItem.type, fromObjItem.ES, fromObjItem.EF, node.duration);
|
|
2582
|
+
if (need > earliestStart) {
|
|
2583
|
+
earliestStart = need;
|
|
2584
|
+
}
|
|
2585
|
+
}
|
|
2586
|
+
}
|
|
2587
|
+
node.ES = earliestStart;
|
|
2588
|
+
node.EF = earliestStart + node.duration;
|
|
2589
|
+
if (node.EF > criticalDuration) {
|
|
2590
|
+
criticalDuration = node.EF;
|
|
2591
|
+
}
|
|
2592
|
+
}
|
|
2593
|
+
// 反向:LS / LF
|
|
2594
|
+
for (let i = orderList.length - 1; i >= 0; i--) {
|
|
2595
|
+
const node = orderList[i];
|
|
2596
|
+
let latestFinish = criticalDuration;
|
|
2597
|
+
for (const lkItem of node.outgoing) {
|
|
2598
|
+
const toObjItem = nodeMap.get('' + lkItem.to);
|
|
2599
|
+
if (toObjItem) {
|
|
2600
|
+
const need = backwardCriticalPathUpperBound(lkItem.type, toObjItem.LS, toObjItem.LF, node.duration);
|
|
2601
|
+
if (need < latestFinish) {
|
|
2602
|
+
latestFinish = need;
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
}
|
|
2606
|
+
node.LF = latestFinish;
|
|
2607
|
+
node.LS = latestFinish - node.duration;
|
|
2608
|
+
}
|
|
2609
|
+
// 关键任务
|
|
2610
|
+
const criticalSet = new Set();
|
|
2611
|
+
const criticalRowIds = [];
|
|
2612
|
+
for (const nodeItem of orderList) {
|
|
2613
|
+
if (Math.abs(nodeItem.LS - nodeItem.ES) < tolerance) {
|
|
2614
|
+
criticalSet.add(nodeItem.rowid);
|
|
2615
|
+
criticalRowIds.push(nodeItem.rowid);
|
|
2616
|
+
criticalRowList.push(nodeItem.row);
|
|
2617
|
+
criticalRowMaps.set(nodeItem.rowid, nodeItem.row);
|
|
2618
|
+
}
|
|
2619
|
+
}
|
|
2620
|
+
// 关键连接线
|
|
2621
|
+
const criticalLinks = [];
|
|
2622
|
+
for (const lkItem of linkList) {
|
|
2623
|
+
const toObjItem = nodeMap.get('' + lkItem.to);
|
|
2624
|
+
const fromObjItem = nodeMap.get('' + lkItem.from);
|
|
2625
|
+
if (!toObjItem || !fromObjItem) {
|
|
2626
|
+
continue;
|
|
2627
|
+
}
|
|
2628
|
+
// 两端必须都是关键任务
|
|
2629
|
+
if (!criticalSet.has(fromObjItem.rowid) || !criticalSet.has(toObjItem.rowid)) {
|
|
2630
|
+
continue;
|
|
2631
|
+
}
|
|
2632
|
+
// 约束必须是连接的
|
|
2633
|
+
if (isCriticalPathLinkTight(lkItem.type, fromObjItem.ES, fromObjItem.EF, toObjItem.ES, toObjItem.EF, tolerance)) {
|
|
2634
|
+
criticalLinks.push(lkItem.raw);
|
|
2635
|
+
criticalLinkKeyMaps.set(getTaskLinkKey(lkItem.from, lkItem.to, lkItem.type), lkItem.raw);
|
|
2636
|
+
}
|
|
2637
|
+
}
|
|
2638
|
+
ganttReactData.criticalLinks = criticalLinks;
|
|
2639
|
+
ganttReactData.criticalRowIds = criticalRowIds;
|
|
2640
|
+
ganttReactData.criticalPathFlag++;
|
|
2641
|
+
}
|
|
2378
2642
|
const calcScrollbar = () => {
|
|
2379
2643
|
const { scrollXWidth, scrollYHeight } = reactData;
|
|
2380
2644
|
const { elemStore } = internalData;
|
|
@@ -3340,7 +3604,11 @@ function createInternalData() {
|
|
|
3340
3604
|
dragLinkToStore: {
|
|
3341
3605
|
rowid: null,
|
|
3342
3606
|
type: 0
|
|
3343
|
-
}
|
|
3607
|
+
},
|
|
3608
|
+
// 关键路径
|
|
3609
|
+
criticalRowList: [],
|
|
3610
|
+
criticalRowMaps: new Map(),
|
|
3611
|
+
criticalLinkKeyMaps: new Map()
|
|
3344
3612
|
};
|
|
3345
3613
|
}
|
|
3346
3614
|
function createReactData() {
|
|
@@ -3390,7 +3658,11 @@ function createReactData() {
|
|
|
3390
3658
|
showSplitAnimat: false,
|
|
3391
3659
|
nowTime: 0,
|
|
3392
3660
|
currLeftSpacing: 0,
|
|
3393
|
-
currRightSpacing: 0
|
|
3661
|
+
currRightSpacing: 0,
|
|
3662
|
+
// 关键路径
|
|
3663
|
+
criticalLinks: [],
|
|
3664
|
+
criticalRowIds: [],
|
|
3665
|
+
criticalPathFlag: 0
|
|
3394
3666
|
};
|
|
3395
3667
|
}
|
|
3396
3668
|
const viewTypeLevelMaps = {
|
|
@@ -3410,7 +3682,7 @@ function getViewTypeLevel(type) {
|
|
|
3410
3682
|
var VxeGanttComponent = defineVxeComponent({
|
|
3411
3683
|
name: 'VxeGantt',
|
|
3412
3684
|
mixins: [],
|
|
3413
|
-
props: Object.assign(Object.assign({}, tableProps), { columns: Array, pagerConfig: Object, proxyConfig: Object, toolbarConfig: Object, formConfig: Object, zoomConfig: Object, links: Array, layouts: Array, taskConfig: Object, taskViewScaleConfig: Object, taskNowLineConfig: Object, taskViewConfig: Object, taskLinkConfig: Object, taskBarConfig: Object, taskBarMilestoneConfig: Object, taskBarSubviewConfig: Object, taskBarTooltipConfig: Object, taskSplitConfig: Object, taskBarResizeConfig: Object, taskBarResizeTooltipConfig: Object, taskBarMoveConfig: Object, taskBarMoveTooltipConfig: Object, size: {
|
|
3685
|
+
props: Object.assign(Object.assign({}, tableProps), { columns: Array, pagerConfig: Object, proxyConfig: Object, toolbarConfig: Object, formConfig: Object, zoomConfig: Object, links: Array, layouts: Array, taskConfig: Object, taskViewScaleConfig: Object, taskNowLineConfig: Object, taskViewConfig: Object, taskLinkConfig: Object, taskBarConfig: Object, taskBarMilestoneConfig: Object, taskCriticalPathConfig: Object, taskBarSubviewConfig: Object, taskBarTooltipConfig: Object, taskSplitConfig: Object, taskBarResizeConfig: Object, taskBarResizeTooltipConfig: Object, taskBarMoveConfig: Object, taskBarMoveTooltipConfig: Object, size: {
|
|
3414
3686
|
type: String,
|
|
3415
3687
|
default: () => getConfig().gantt.size || getConfig().size
|
|
3416
3688
|
} }),
|
|
@@ -3522,6 +3794,9 @@ var VxeGanttComponent = defineVxeComponent({
|
|
|
3522
3794
|
const computeTaskBarMilestoneOpts = computed(() => {
|
|
3523
3795
|
return Object.assign({}, getConfig().gantt.taskBarMilestoneConfig, props.taskBarMilestoneConfig);
|
|
3524
3796
|
});
|
|
3797
|
+
const computeTaskCriticalPathOpts = computed(() => {
|
|
3798
|
+
return Object.assign({}, getConfig().gantt.taskCriticalPathConfig, props.taskCriticalPathConfig);
|
|
3799
|
+
});
|
|
3525
3800
|
const computeTaskBarSubviewOpts = computed(() => {
|
|
3526
3801
|
return Object.assign({}, getConfig().gantt.taskBarSubviewConfig, props.taskBarSubviewConfig);
|
|
3527
3802
|
});
|
|
@@ -3593,6 +3868,10 @@ var VxeGanttComponent = defineVxeComponent({
|
|
|
3593
3868
|
const scrollbarOpts = computeScrollbarOpts.value;
|
|
3594
3869
|
return !!(scrollbarOpts.y && scrollbarOpts.y.position === 'left');
|
|
3595
3870
|
});
|
|
3871
|
+
const computeCriticalPathVisible = computed(() => {
|
|
3872
|
+
const taskBarOpts = computeTaskBarOpts.value;
|
|
3873
|
+
return taskBarOpts.showCriticalPath;
|
|
3874
|
+
});
|
|
3596
3875
|
const computeWrapperStyle = computed(() => {
|
|
3597
3876
|
const { height, maxHeight, taskBarSubviewConfig } = props;
|
|
3598
3877
|
const { isZMax, tZindex, overflowY, scrollbarWidth } = reactData;
|
|
@@ -3600,12 +3879,17 @@ var VxeGanttComponent = defineVxeComponent({
|
|
|
3600
3879
|
const { viewStyle, tableStyle } = taskViewOpts;
|
|
3601
3880
|
const taskBarOpts = computeTaskBarOpts.value;
|
|
3602
3881
|
const { barStyle } = taskBarOpts;
|
|
3882
|
+
const taskCriticalPathOpts = computeTaskCriticalPathOpts.value;
|
|
3883
|
+
const { lineColor: cpLineColor } = taskCriticalPathOpts;
|
|
3603
3884
|
const taskBarSubviewOpts = computeTaskBarSubviewOpts.value;
|
|
3604
3885
|
const taskNowLineOpts = computeTaskNowLineOpts.value;
|
|
3605
3886
|
const { fontColor: nlfColor, bgColor: nlbgColor, width: nlWidth } = taskNowLineOpts;
|
|
3606
3887
|
const stys = {
|
|
3607
3888
|
'--vxe-ui-gantt-scrollbar-width': (overflowY && scrollbarWidth ? scrollbarWidth : 0) + 'px'
|
|
3608
3889
|
};
|
|
3890
|
+
if (cpLineColor) {
|
|
3891
|
+
stys['--vxe-ui-gantt-view-bar-critical-path-line-color'] = cpLineColor;
|
|
3892
|
+
}
|
|
3609
3893
|
if (isZMax) {
|
|
3610
3894
|
stys.zIndex = tZindex;
|
|
3611
3895
|
}
|
|
@@ -3806,6 +4090,7 @@ var VxeGanttComponent = defineVxeComponent({
|
|
|
3806
4090
|
computeTaskBarResizeTooltipOpts,
|
|
3807
4091
|
computeTaskSplitOpts,
|
|
3808
4092
|
computeTaskBarMilestoneOpts,
|
|
4093
|
+
computeTaskCriticalPathOpts,
|
|
3809
4094
|
computeTaskBarSubviewOpts,
|
|
3810
4095
|
computeTaskBarTooltipOpts,
|
|
3811
4096
|
computeTaskLinkOpts,
|
|
@@ -4866,6 +5151,10 @@ var VxeGanttComponent = defineVxeComponent({
|
|
|
4866
5151
|
return handleZoom();
|
|
4867
5152
|
},
|
|
4868
5153
|
getFormData,
|
|
5154
|
+
/**
|
|
5155
|
+
* 已废弃,被 getFormFlatItems 替换
|
|
5156
|
+
* @deprecated
|
|
5157
|
+
*/
|
|
4869
5158
|
getFormItems(itemIndex) {
|
|
4870
5159
|
const formOpts = computeFormOpts.value;
|
|
4871
5160
|
const { formConfig } = props;
|
|
@@ -4874,8 +5163,30 @@ var VxeGanttComponent = defineVxeComponent({
|
|
|
4874
5163
|
XEUtils.eachTree(formConfig && isEnableConf(formOpts) && items ? items : [], item => {
|
|
4875
5164
|
itemList.push(item);
|
|
4876
5165
|
}, { children: 'children' });
|
|
5166
|
+
// errLog('vxe.error.delFunc', ['getFormItems', 'getFormFlatItems'])
|
|
4877
5167
|
return XEUtils.isUndefined(itemIndex) ? itemList : itemList[itemIndex];
|
|
4878
5168
|
},
|
|
5169
|
+
getFormFlatItems() {
|
|
5170
|
+
const $form = refForm.value;
|
|
5171
|
+
if ($form) {
|
|
5172
|
+
return $form.getFlatItems();
|
|
5173
|
+
}
|
|
5174
|
+
return [];
|
|
5175
|
+
},
|
|
5176
|
+
getFormNestedItems() {
|
|
5177
|
+
const $form = refForm.value;
|
|
5178
|
+
if ($form) {
|
|
5179
|
+
return $form.getNestedItems();
|
|
5180
|
+
}
|
|
5181
|
+
return [];
|
|
5182
|
+
},
|
|
5183
|
+
getFormItemByField(field) {
|
|
5184
|
+
const $form = refForm.value;
|
|
5185
|
+
if ($form) {
|
|
5186
|
+
return $form.getItemByField(field);
|
|
5187
|
+
}
|
|
5188
|
+
return null;
|
|
5189
|
+
},
|
|
4879
5190
|
resetForm() {
|
|
4880
5191
|
const $form = refForm.value;
|
|
4881
5192
|
if ($form) {
|
|
@@ -5098,6 +5409,15 @@ var VxeGanttComponent = defineVxeComponent({
|
|
|
5098
5409
|
});
|
|
5099
5410
|
}
|
|
5100
5411
|
return nextTick();
|
|
5412
|
+
},
|
|
5413
|
+
getCriticalPath() {
|
|
5414
|
+
const { criticalRowIds, criticalLinks } = reactData;
|
|
5415
|
+
const { criticalRowMaps } = internalData;
|
|
5416
|
+
return {
|
|
5417
|
+
rowIds: criticalRowIds.slice(0),
|
|
5418
|
+
rows: Array.from(criticalRowMaps.values()),
|
|
5419
|
+
links: criticalLinks.slice(0)
|
|
5420
|
+
};
|
|
5101
5421
|
}
|
|
5102
5422
|
};
|
|
5103
5423
|
const ganttPrivateMethods = {
|
|
@@ -5391,7 +5711,7 @@ var VxeGanttComponent = defineVxeComponent({
|
|
|
5391
5711
|
// 处理插槽
|
|
5392
5712
|
formOpts.items.forEach((item) => {
|
|
5393
5713
|
XEUtils.each(item.slots, (func) => {
|
|
5394
|
-
if (!XEUtils.isFunction(func)) {
|
|
5714
|
+
if (func && !XEUtils.isFunction(func)) {
|
|
5395
5715
|
if (slots[func]) {
|
|
5396
5716
|
formSlots[func] = slots[func];
|
|
5397
5717
|
}
|
|
@@ -5837,8 +6157,15 @@ var VxeGanttComponent = defineVxeComponent({
|
|
|
5837
6157
|
watch(() => props.proxyConfig, () => {
|
|
5838
6158
|
initProxy();
|
|
5839
6159
|
});
|
|
6160
|
+
const reViewFlag = ref(0);
|
|
5840
6161
|
watch(computeTaskViewScales, () => {
|
|
5841
6162
|
handleTaskScaleConfig();
|
|
6163
|
+
reViewFlag.value++;
|
|
6164
|
+
});
|
|
6165
|
+
watch(computeCriticalPathVisible, () => {
|
|
6166
|
+
reViewFlag.value++;
|
|
6167
|
+
});
|
|
6168
|
+
watch(reViewFlag, () => {
|
|
5842
6169
|
$xeGantt.refreshTaskView();
|
|
5843
6170
|
});
|
|
5844
6171
|
watch(computeTaskLinkStyle, () => {
|
|
@@ -5941,43 +6268,6 @@ var VxeGanttComponent = defineVxeComponent({
|
|
|
5941
6268
|
}
|
|
5942
6269
|
});
|
|
5943
6270
|
|
|
5944
|
-
/**
|
|
5945
|
-
* 依赖线枚举类型
|
|
5946
|
-
*/
|
|
5947
|
-
var VxeGanttDependencyType;
|
|
5948
|
-
(function (VxeGanttDependencyType) {
|
|
5949
|
-
/**
|
|
5950
|
-
* 结束后才开始,表示一个任务必须在另一个任务开始之前完成
|
|
5951
|
-
*/
|
|
5952
|
-
VxeGanttDependencyType[VxeGanttDependencyType["FinishToStart"] = 0] = "FinishToStart";
|
|
5953
|
-
/**
|
|
5954
|
-
* 开始到结束,表示从某个过程的开始到结束的整个过程
|
|
5955
|
-
*/
|
|
5956
|
-
VxeGanttDependencyType[VxeGanttDependencyType["StartToFinish"] = 1] = "StartToFinish";
|
|
5957
|
-
/**
|
|
5958
|
-
* 开始后才开始,表示一个活动结束了,另一个活动才能开始,它们之间按先后顺序进行
|
|
5959
|
-
*/
|
|
5960
|
-
VxeGanttDependencyType[VxeGanttDependencyType["StartToStart"] = 2] = "StartToStart";
|
|
5961
|
-
/**
|
|
5962
|
-
* 完成到完成,表示一个任务必须在另一个任务完成之后才能完成
|
|
5963
|
-
*/
|
|
5964
|
-
VxeGanttDependencyType[VxeGanttDependencyType["FinishToFinish"] = 3] = "FinishToFinish";
|
|
5965
|
-
})(VxeGanttDependencyType || (VxeGanttDependencyType = {}));
|
|
5966
|
-
/**
|
|
5967
|
-
* 任务渲染类型
|
|
5968
|
-
*/
|
|
5969
|
-
var VxeGanttTaskType;
|
|
5970
|
-
(function (VxeGanttTaskType) {
|
|
5971
|
-
/**
|
|
5972
|
-
* 里程碑类型,该类型节点不需要结束日期
|
|
5973
|
-
*/
|
|
5974
|
-
VxeGanttTaskType["Milestone"] = "milestone";
|
|
5975
|
-
/**
|
|
5976
|
-
* 子视图类型,该类型会将子任务渲染到一行,无需开始日期和结束日期
|
|
5977
|
-
*/
|
|
5978
|
-
VxeGanttTaskType["Subview"] = "subview";
|
|
5979
|
-
})(VxeGanttTaskType || (VxeGanttTaskType = {}));
|
|
5980
|
-
|
|
5981
6271
|
const VxeGantt = Object.assign({}, VxeGanttComponent, {
|
|
5982
6272
|
install(app) {
|
|
5983
6273
|
checkDependVersion();
|