vxe-gantt 3.7.3 → 3.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/es/gantt/src/gantt-chart.js +5 -2
- package/es/gantt/src/gantt-view.js +225 -0
- package/es/gantt/src/gantt.js +78 -5
- 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 +6 -1
- package/lib/gantt/src/gantt-chart.min.js +1 -1
- package/lib/gantt/src/gantt-view.js +278 -0
- package/lib/gantt/src/gantt-view.min.js +1 -1
- package/lib/gantt/src/gantt.js +79 -4
- 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 +1813 -71
- 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 +263 -1
- package/packages/gantt/src/gantt.ts +87 -4
- 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
|
@@ -3,22 +3,46 @@ import { defineVxeComponent } from '../../ui/src/comp'
|
|
|
3
3
|
import { VxeUI } from '@vxe-ui/core'
|
|
4
4
|
import { setScrollTop, setScrollLeft, removeClass, addClass, hasClass } from '../../ui/src/dom'
|
|
5
5
|
import { getRefElem, getTaskBarLeft, getTaskBarWidth, hasMilestoneTask, getTaskType, hasSubviewTask } from './util'
|
|
6
|
+
import { VxeGanttDependencyType } from './static'
|
|
6
7
|
import XEUtils from 'xe-utils'
|
|
7
8
|
import GanttViewHeaderComponent from './gantt-header'
|
|
8
9
|
import GanttViewBodyComponent from './gantt-body'
|
|
9
10
|
import GanttViewFooterComponent from './gantt-footer'
|
|
10
11
|
|
|
11
12
|
import type { TableReactData, TableInternalData, VxeTableConstructor, VxeTableMethods, VxeTablePrivateMethods } from 'vxe-table'
|
|
12
|
-
import type { VxeGanttViewConstructor, GanttViewReactData, VxeGanttDefines, VxeGanttViewPrivateMethods, GanttViewInternalData, VxeGanttConstructor, VxeGanttPrivateMethods } from '../../../types'
|
|
13
|
+
import type { VxeGanttViewConstructor, GanttViewReactData, VxeGanttDefines, VxeGanttPropTypes, VxeGanttViewPrivateMethods, GanttViewInternalData, VxeGanttConstructor, VxeGanttPrivateMethods } from '../../../types'
|
|
14
|
+
|
|
15
|
+
interface CpmLink extends VxeGanttPropTypes.Link {
|
|
16
|
+
raw: VxeGanttPropTypes.Link
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface CpmItem {
|
|
20
|
+
row: any
|
|
21
|
+
rowid: string
|
|
22
|
+
duration: number
|
|
23
|
+
incoming: CpmLink[]
|
|
24
|
+
outgoing: CpmLink[]
|
|
25
|
+
indeg: number
|
|
26
|
+
ES: number
|
|
27
|
+
EF: number
|
|
28
|
+
LS: number
|
|
29
|
+
LF: number
|
|
30
|
+
}
|
|
13
31
|
|
|
14
32
|
const { globalEvents } = VxeUI
|
|
15
33
|
|
|
34
|
+
const { FinishToStart, StartToFinish, StartToStart, FinishToFinish } = VxeGanttDependencyType
|
|
35
|
+
|
|
16
36
|
const sourceType = 'gantt'
|
|
17
37
|
const secondMs = 1000
|
|
18
38
|
const minuteMs = 1000 * 60
|
|
19
39
|
const hourMs = 1000 * 60 * 60
|
|
20
40
|
const dayMs = hourMs * 24
|
|
21
41
|
|
|
42
|
+
function getTaskLinkKey (from: string | number, to: string | number, type?: VxeGanttDependencyType) {
|
|
43
|
+
return from + '_' + to + '_' + (type || 0)
|
|
44
|
+
}
|
|
45
|
+
|
|
22
46
|
function createInternalData (): GanttViewInternalData {
|
|
23
47
|
return {
|
|
24
48
|
xeTable: null,
|
|
@@ -827,6 +851,9 @@ function handleUpdateData ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewP
|
|
|
827
851
|
const internalData = $xeGanttView.internalData
|
|
828
852
|
|
|
829
853
|
const ganttProps = $xeGantt
|
|
854
|
+
const ganttReactData = $xeGantt.reactData
|
|
855
|
+
|
|
856
|
+
const { linkList } = ganttReactData
|
|
830
857
|
const { treeConfig } = ganttProps
|
|
831
858
|
const { scrollXStore } = internalData
|
|
832
859
|
const $xeTable = internalData.xeTable
|
|
@@ -834,6 +861,7 @@ function handleUpdateData ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewP
|
|
|
834
861
|
const edMaps: Record<string, any> = {}
|
|
835
862
|
let minDate: Date | null = null
|
|
836
863
|
let maxDate: Date | null = null
|
|
864
|
+
const allList: any[] = []
|
|
837
865
|
if ($xeTable) {
|
|
838
866
|
const startField = $xeGantt.computeStartField
|
|
839
867
|
const endField = $xeGantt.computeEndField
|
|
@@ -870,6 +898,7 @@ function handleUpdateData ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewP
|
|
|
870
898
|
maxDate = endDate
|
|
871
899
|
}
|
|
872
900
|
}
|
|
901
|
+
allList.push(row)
|
|
873
902
|
}
|
|
874
903
|
|
|
875
904
|
if (isRowGroupStatus) {
|
|
@@ -892,6 +921,239 @@ function handleUpdateData ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewP
|
|
|
892
921
|
internalData.startMaps = sdMaps
|
|
893
922
|
internalData.endMaps = edMaps
|
|
894
923
|
handleParseColumn($xeGanttView)
|
|
924
|
+
handleCriticalPath($xeGanttView, allList, linkList)
|
|
925
|
+
}
|
|
926
|
+
|
|
927
|
+
/**
|
|
928
|
+
* 正向:后置 ES 的下连接线
|
|
929
|
+
*/
|
|
930
|
+
function forwardCriticalPathLowerBound (linkType: VxeGanttDependencyType, predES: number, predEF: number, duration: number): number {
|
|
931
|
+
switch (linkType) {
|
|
932
|
+
case FinishToStart:
|
|
933
|
+
return predEF
|
|
934
|
+
case StartToFinish:
|
|
935
|
+
return predES - duration
|
|
936
|
+
case StartToStart:
|
|
937
|
+
return predES
|
|
938
|
+
case FinishToFinish:
|
|
939
|
+
return predEF - duration
|
|
940
|
+
default:
|
|
941
|
+
return 0
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
|
|
945
|
+
/**
|
|
946
|
+
* 反向:前置 LF 的上连接线
|
|
947
|
+
*/
|
|
948
|
+
function backwardCriticalPathUpperBound (linkType: VxeGanttDependencyType, succLS: number, succLF: number, duration: number): number {
|
|
949
|
+
switch (linkType) {
|
|
950
|
+
case FinishToStart:
|
|
951
|
+
return succLS
|
|
952
|
+
case StartToFinish:
|
|
953
|
+
return succLF + duration
|
|
954
|
+
case StartToStart:
|
|
955
|
+
return succLS + duration
|
|
956
|
+
case FinishToFinish:
|
|
957
|
+
return succLF
|
|
958
|
+
default:
|
|
959
|
+
return -1
|
|
960
|
+
}
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
/**
|
|
964
|
+
* 关键边:两端都关键时,约束是否连接
|
|
965
|
+
*/
|
|
966
|
+
function isCriticalPathLinkTight (linkType: VxeGanttDependencyType, fromES: number, fromEF: number, toES: number, toEF: number, tolerance: number) {
|
|
967
|
+
switch (linkType) {
|
|
968
|
+
case FinishToStart:
|
|
969
|
+
return Math.abs(fromEF - toES) < tolerance
|
|
970
|
+
case StartToFinish:
|
|
971
|
+
return Math.abs(fromES - toEF) < tolerance
|
|
972
|
+
case StartToStart:
|
|
973
|
+
return Math.abs(fromES - toES) < tolerance
|
|
974
|
+
case FinishToFinish:
|
|
975
|
+
return Math.abs(fromEF - toEF) < tolerance
|
|
976
|
+
default:
|
|
977
|
+
return false
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
|
|
981
|
+
export function handleCriticalPath ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods, data: any[], links: VxeGanttPropTypes.Links) {
|
|
982
|
+
const $xeGantt = $xeGanttView.$xeGantt
|
|
983
|
+
const internalData = $xeGanttView.internalData
|
|
984
|
+
const ganttReactData = $xeGantt.reactData
|
|
985
|
+
const ganttInternalData = $xeGantt.internalData
|
|
986
|
+
|
|
987
|
+
const taskBarOpts = $xeGantt.computeTaskBarOpts
|
|
988
|
+
const $xeTable = internalData.xeTable
|
|
989
|
+
|
|
990
|
+
const criticalRowList: any[] = []
|
|
991
|
+
const criticalRowMaps = new Map<string, any>()
|
|
992
|
+
const criticalLinkKeyMaps = new Map<string, VxeGanttPropTypes.Link>()
|
|
993
|
+
|
|
994
|
+
ganttInternalData.criticalRowList = criticalRowList
|
|
995
|
+
ganttInternalData.criticalRowMaps = criticalRowMaps
|
|
996
|
+
ganttInternalData.criticalLinkKeyMaps = criticalLinkKeyMaps
|
|
997
|
+
if (!taskBarOpts.showCriticalPath || !links.length || !data.length || !$xeTable) {
|
|
998
|
+
if (ganttReactData.criticalRowIds.length || ganttReactData.criticalLinks.length) {
|
|
999
|
+
ganttReactData.criticalPathFlag++
|
|
1000
|
+
}
|
|
1001
|
+
ganttReactData.criticalLinks = []
|
|
1002
|
+
ganttReactData.criticalRowIds = []
|
|
1003
|
+
return
|
|
1004
|
+
}
|
|
1005
|
+
const { chartMaps } = internalData
|
|
1006
|
+
const tolerance = 1e-6
|
|
1007
|
+
|
|
1008
|
+
const nodeMap = new Map<string, CpmItem>()
|
|
1009
|
+
for (const row of data) {
|
|
1010
|
+
const rowid = $xeTable.getRowid(row)
|
|
1011
|
+
const chartRest = chartMaps[rowid]
|
|
1012
|
+
nodeMap.set(rowid, {
|
|
1013
|
+
row,
|
|
1014
|
+
rowid: rowid,
|
|
1015
|
+
duration: chartRest ? chartRest.oWidthSize : 0,
|
|
1016
|
+
incoming: [],
|
|
1017
|
+
outgoing: [],
|
|
1018
|
+
indeg: 0,
|
|
1019
|
+
ES: 0,
|
|
1020
|
+
EF: 0,
|
|
1021
|
+
LS: 0,
|
|
1022
|
+
LF: 0
|
|
1023
|
+
})
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
// 边界
|
|
1027
|
+
const linkList: CpmLink[] = []
|
|
1028
|
+
for (const link of links) {
|
|
1029
|
+
const fromKey = '' + link.from
|
|
1030
|
+
const toKey = '' + link.to
|
|
1031
|
+
if (!nodeMap.has(fromKey) || !nodeMap.has(toKey) || fromKey === toKey) {
|
|
1032
|
+
continue
|
|
1033
|
+
}
|
|
1034
|
+
const lkItemitem: CpmLink = {
|
|
1035
|
+
from: link.from,
|
|
1036
|
+
to: link.to,
|
|
1037
|
+
type: XEUtils.toNumber(link.type) || 0,
|
|
1038
|
+
raw: link
|
|
1039
|
+
}
|
|
1040
|
+
linkList.push(lkItemitem)
|
|
1041
|
+
const toObjItem = nodeMap.get('' + link.to)
|
|
1042
|
+
const fromObjItem = nodeMap.get('' + link.from)
|
|
1043
|
+
if (fromObjItem) {
|
|
1044
|
+
fromObjItem.outgoing.push(lkItemitem)
|
|
1045
|
+
}
|
|
1046
|
+
if (toObjItem) {
|
|
1047
|
+
toObjItem.incoming.push(lkItemitem)
|
|
1048
|
+
toObjItem.indeg++
|
|
1049
|
+
}
|
|
1050
|
+
}
|
|
1051
|
+
|
|
1052
|
+
// 拓扑排序 + 环检测
|
|
1053
|
+
const queueList: CpmItem[] = []
|
|
1054
|
+
nodeMap.forEach(nodeitem => {
|
|
1055
|
+
if (nodeitem.indeg === 0) {
|
|
1056
|
+
queueList.push(nodeitem)
|
|
1057
|
+
}
|
|
1058
|
+
})
|
|
1059
|
+
|
|
1060
|
+
const orderList: CpmItem[] = []
|
|
1061
|
+
for (let head = 0; head < queueList.length; head++) {
|
|
1062
|
+
const node = queueList[head]
|
|
1063
|
+
orderList.push(node)
|
|
1064
|
+
for (const lkItemitem of node.outgoing) {
|
|
1065
|
+
const toObjItem = nodeMap.get('' + lkItemitem.to)
|
|
1066
|
+
if (toObjItem) {
|
|
1067
|
+
const nextDeg = toObjItem.indeg - 1
|
|
1068
|
+
toObjItem.indeg = nextDeg
|
|
1069
|
+
if (nextDeg === 0) {
|
|
1070
|
+
queueList.push(nodeMap.get('' + lkItemitem.to)!)
|
|
1071
|
+
}
|
|
1072
|
+
}
|
|
1073
|
+
}
|
|
1074
|
+
}
|
|
1075
|
+
|
|
1076
|
+
if (orderList.length !== nodeMap.size) {
|
|
1077
|
+
// 异常数据,依赖图中存在环
|
|
1078
|
+
if (ganttReactData.criticalRowIds.length || ganttReactData.criticalLinks.length) {
|
|
1079
|
+
ganttReactData.criticalPathFlag++
|
|
1080
|
+
}
|
|
1081
|
+
ganttReactData.criticalLinks = []
|
|
1082
|
+
ganttReactData.criticalRowIds = []
|
|
1083
|
+
return
|
|
1084
|
+
}
|
|
1085
|
+
|
|
1086
|
+
// 正向:ES / EF
|
|
1087
|
+
let criticalDuration = 0
|
|
1088
|
+
for (const node of orderList) {
|
|
1089
|
+
let earliestStart = 0
|
|
1090
|
+
for (const lkItem of node.incoming) {
|
|
1091
|
+
const fromObjItem = nodeMap.get('' + lkItem.from)
|
|
1092
|
+
if (fromObjItem) {
|
|
1093
|
+
const need = forwardCriticalPathLowerBound(lkItem.type, fromObjItem.ES, fromObjItem.EF, node.duration)
|
|
1094
|
+
if (need > earliestStart) {
|
|
1095
|
+
earliestStart = need
|
|
1096
|
+
}
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
node.ES = earliestStart
|
|
1100
|
+
node.EF = earliestStart + node.duration
|
|
1101
|
+
if (node.EF > criticalDuration) {
|
|
1102
|
+
criticalDuration = node.EF
|
|
1103
|
+
}
|
|
1104
|
+
}
|
|
1105
|
+
|
|
1106
|
+
// 反向:LS / LF
|
|
1107
|
+
for (let i = orderList.length - 1; i >= 0; i--) {
|
|
1108
|
+
const node = orderList[i]
|
|
1109
|
+
let latestFinish = criticalDuration
|
|
1110
|
+
for (const lkItem of node.outgoing) {
|
|
1111
|
+
const toObjItem = nodeMap.get('' + lkItem.to)
|
|
1112
|
+
if (toObjItem) {
|
|
1113
|
+
const need = backwardCriticalPathUpperBound(lkItem.type, toObjItem.LS, toObjItem.LF, node.duration)
|
|
1114
|
+
if (need < latestFinish) {
|
|
1115
|
+
latestFinish = need
|
|
1116
|
+
}
|
|
1117
|
+
}
|
|
1118
|
+
}
|
|
1119
|
+
node.LF = latestFinish
|
|
1120
|
+
node.LS = latestFinish - node.duration
|
|
1121
|
+
}
|
|
1122
|
+
|
|
1123
|
+
// 关键任务
|
|
1124
|
+
const criticalSet = new Set<string>()
|
|
1125
|
+
const criticalRowIds: string[] = []
|
|
1126
|
+
for (const nodeItem of orderList) {
|
|
1127
|
+
if (Math.abs(nodeItem.LS - nodeItem.ES) < tolerance) {
|
|
1128
|
+
criticalSet.add(nodeItem.rowid)
|
|
1129
|
+
criticalRowIds.push(nodeItem.rowid)
|
|
1130
|
+
criticalRowList.push(nodeItem.row)
|
|
1131
|
+
criticalRowMaps.set(nodeItem.rowid, nodeItem.row)
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
// 关键连接线
|
|
1136
|
+
const criticalLinks: VxeGanttPropTypes.Links = []
|
|
1137
|
+
for (const lkItem of linkList) {
|
|
1138
|
+
const toObjItem = nodeMap.get('' + lkItem.to)
|
|
1139
|
+
const fromObjItem = nodeMap.get('' + lkItem.from)
|
|
1140
|
+
if (!toObjItem || !fromObjItem) {
|
|
1141
|
+
continue
|
|
1142
|
+
}
|
|
1143
|
+
// 两端必须都是关键任务
|
|
1144
|
+
if (!criticalSet.has(fromObjItem.rowid) || !criticalSet.has(toObjItem.rowid)) {
|
|
1145
|
+
continue
|
|
1146
|
+
}
|
|
1147
|
+
// 约束必须是连接的
|
|
1148
|
+
if (isCriticalPathLinkTight(lkItem.type, fromObjItem.ES, fromObjItem.EF, toObjItem.ES, toObjItem.EF, tolerance)) {
|
|
1149
|
+
criticalLinks.push(lkItem.raw)
|
|
1150
|
+
criticalLinkKeyMaps.set(getTaskLinkKey(lkItem.from, lkItem.to, lkItem.type), lkItem.raw)
|
|
1151
|
+
}
|
|
1152
|
+
}
|
|
1153
|
+
|
|
1154
|
+
ganttReactData.criticalLinks = criticalLinks
|
|
1155
|
+
ganttReactData.criticalRowIds = criticalRowIds
|
|
1156
|
+
ganttReactData.criticalPathFlag++
|
|
895
1157
|
}
|
|
896
1158
|
|
|
897
1159
|
function calcScrollbar ($xeGanttView: VxeGanttViewConstructor & VxeGanttViewPrivateMethods) {
|
|
@@ -90,7 +90,11 @@ function createInternalData (): GanttInternalData {
|
|
|
90
90
|
dragLinkToStore: {
|
|
91
91
|
rowid: null,
|
|
92
92
|
type: 0
|
|
93
|
-
}
|
|
93
|
+
},
|
|
94
|
+
// 关键路径
|
|
95
|
+
criticalRowList: [],
|
|
96
|
+
criticalRowMaps: new Map(),
|
|
97
|
+
criticalLinkKeyMaps: new Map()
|
|
94
98
|
}
|
|
95
99
|
}
|
|
96
100
|
|
|
@@ -144,7 +148,12 @@ function createReactData (): GanttReactData {
|
|
|
144
148
|
|
|
145
149
|
nowTime: 0,
|
|
146
150
|
currLeftSpacing: 0,
|
|
147
|
-
currRightSpacing: 0
|
|
151
|
+
currRightSpacing: 0,
|
|
152
|
+
|
|
153
|
+
// 关键路径
|
|
154
|
+
criticalLinks: [],
|
|
155
|
+
criticalRowIds: [],
|
|
156
|
+
criticalPathFlag: 0
|
|
148
157
|
}
|
|
149
158
|
}
|
|
150
159
|
|
|
@@ -192,6 +201,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
|
|
|
192
201
|
taskLinkConfig: Object as PropType<VxeGanttPropTypes.TaskLinkConfig>,
|
|
193
202
|
taskBarConfig: Object as PropType<VxeGanttPropTypes.TaskBarConfig>,
|
|
194
203
|
taskBarMilestoneConfig: Object as PropType<VxeGanttPropTypes.TaskBarMilestoneConfig>,
|
|
204
|
+
taskCriticalPathConfig: Object as PropType<VxeGanttPropTypes.TaskCriticalPathConfig>,
|
|
195
205
|
taskBarSubviewConfig: Object as PropType<VxeGanttPropTypes.TaskBarSubviewConfig>,
|
|
196
206
|
taskBarTooltipConfig: Object as PropType<VxeGanttPropTypes.TaskBarTooltipConfig>,
|
|
197
207
|
taskSplitConfig: Object as PropType<VxeGanttPropTypes.TaskSplitConfig>,
|
|
@@ -223,7 +233,8 @@ export default /* define-vxe-component start */ defineVxeComponent({
|
|
|
223
233
|
return {
|
|
224
234
|
xID,
|
|
225
235
|
reactData,
|
|
226
|
-
internalData
|
|
236
|
+
internalData,
|
|
237
|
+
reViewFlag: 0
|
|
227
238
|
}
|
|
228
239
|
},
|
|
229
240
|
computed: {
|
|
@@ -338,6 +349,12 @@ export default /* define-vxe-component start */ defineVxeComponent({
|
|
|
338
349
|
|
|
339
350
|
return Object.assign({}, getConfig().gantt.taskBarMilestoneConfig, props.taskBarMilestoneConfig)
|
|
340
351
|
},
|
|
352
|
+
computeTaskCriticalPathOpts () {
|
|
353
|
+
const $xeGantt = this
|
|
354
|
+
const props = $xeGantt
|
|
355
|
+
|
|
356
|
+
return Object.assign({}, getConfig().gantt.taskCriticalPathConfig, props.taskCriticalPathConfig)
|
|
357
|
+
},
|
|
341
358
|
computeTaskBarSubviewOpts () {
|
|
342
359
|
const $xeGantt = this
|
|
343
360
|
const props = $xeGantt
|
|
@@ -458,6 +475,12 @@ export default /* define-vxe-component start */ defineVxeComponent({
|
|
|
458
475
|
const scrollbarOpts = $xeGantt.computeScrollbarOpts as VxeTablePropTypes.ScrollbarConfig
|
|
459
476
|
return !!(scrollbarOpts.y && scrollbarOpts.y.position === 'left')
|
|
460
477
|
},
|
|
478
|
+
computeCriticalPathVisible () {
|
|
479
|
+
const $xeGantt = this
|
|
480
|
+
|
|
481
|
+
const taskBarOpts = $xeGantt.computeTaskBarOpts as VxeGanttPropTypes.TaskBarConfig
|
|
482
|
+
return taskBarOpts.showCriticalPath
|
|
483
|
+
},
|
|
461
484
|
computeWrapperStyle () {
|
|
462
485
|
const $xeGantt = this
|
|
463
486
|
const props = $xeGantt
|
|
@@ -469,12 +492,17 @@ export default /* define-vxe-component start */ defineVxeComponent({
|
|
|
469
492
|
const { viewStyle, tableStyle } = taskViewOpts
|
|
470
493
|
const taskBarOpts = $xeGantt.computeTaskBarOpts as VxeGanttPropTypes.TaskBarConfig
|
|
471
494
|
const { barStyle } = taskBarOpts
|
|
495
|
+
const taskCriticalPathOpts = $xeGantt.computeTaskCriticalPathOpts
|
|
496
|
+
const { lineColor: cpLineColor } = taskCriticalPathOpts
|
|
472
497
|
const taskBarSubviewOpts = $xeGantt.computeTaskBarSubviewOpts
|
|
473
498
|
const taskNowLineOpts = $xeGantt.computeTaskNowLineOpts
|
|
474
499
|
const { fontColor: nlfColor, bgColor: nlbgColor, width: nlWidth } = taskNowLineOpts
|
|
475
500
|
const stys: VxeComponentStyleType = {
|
|
476
501
|
'--vxe-ui-gantt-scrollbar-width': (overflowY && scrollbarWidth ? scrollbarWidth : 0) + 'px'
|
|
477
502
|
}
|
|
503
|
+
if (cpLineColor) {
|
|
504
|
+
stys['--vxe-ui-gantt-view-bar-critical-path-line-color'] = cpLineColor
|
|
505
|
+
}
|
|
478
506
|
if (isZMax) {
|
|
479
507
|
stys.zIndex = tZindex
|
|
480
508
|
} else {
|
|
@@ -710,6 +738,16 @@ export default /* define-vxe-component start */ defineVxeComponent({
|
|
|
710
738
|
const $xeGantt = this
|
|
711
739
|
|
|
712
740
|
$xeGantt.handleTaskScaleConfig()
|
|
741
|
+
$xeGantt.reViewFlag++
|
|
742
|
+
},
|
|
743
|
+
computeCriticalPathVisible () {
|
|
744
|
+
const $xeGantt = this
|
|
745
|
+
|
|
746
|
+
$xeGantt.reViewFlag++
|
|
747
|
+
},
|
|
748
|
+
reViewFlag () {
|
|
749
|
+
const $xeGantt = this
|
|
750
|
+
|
|
713
751
|
$xeGantt.refreshTaskView()
|
|
714
752
|
},
|
|
715
753
|
computeTaskLinkStyle () {
|
|
@@ -1764,6 +1802,10 @@ export default /* define-vxe-component start */ defineVxeComponent({
|
|
|
1764
1802
|
const formOpts = $xeGantt.computeFormOpts
|
|
1765
1803
|
return proxyConfig && isEnableConf(proxyOpts) && proxyOpts.form ? formData : formOpts.data
|
|
1766
1804
|
},
|
|
1805
|
+
/**
|
|
1806
|
+
* 已废弃,被 getFormFlatItems 替换
|
|
1807
|
+
* @deprecated
|
|
1808
|
+
*/
|
|
1767
1809
|
getFormItems (itemIndex?: number): any {
|
|
1768
1810
|
const $xeGantt = this
|
|
1769
1811
|
const props = $xeGantt
|
|
@@ -1775,8 +1817,36 @@ export default /* define-vxe-component start */ defineVxeComponent({
|
|
|
1775
1817
|
XEUtils.eachTree(formConfig && isEnableConf(formOpts) && items ? items : [], item => {
|
|
1776
1818
|
itemList.push(item)
|
|
1777
1819
|
}, { children: 'children' })
|
|
1820
|
+
// errLog('vxe.error.delFunc', ['getFormItems', 'getFormFlatItems'])
|
|
1778
1821
|
return XEUtils.isUndefined(itemIndex) ? itemList : itemList[itemIndex]
|
|
1779
1822
|
},
|
|
1823
|
+
getFormFlatItems () {
|
|
1824
|
+
const $xeGantt = this
|
|
1825
|
+
|
|
1826
|
+
const $form = $xeGantt.$refs.refForm as VxeFormInstance
|
|
1827
|
+
if ($form) {
|
|
1828
|
+
return $form.getFlatItems()
|
|
1829
|
+
}
|
|
1830
|
+
return []
|
|
1831
|
+
},
|
|
1832
|
+
getFormNestedItems () {
|
|
1833
|
+
const $xeGantt = this
|
|
1834
|
+
|
|
1835
|
+
const $form = $xeGantt.$refs.refForm as VxeFormInstance
|
|
1836
|
+
if ($form) {
|
|
1837
|
+
return $form.getNestedItems()
|
|
1838
|
+
}
|
|
1839
|
+
return []
|
|
1840
|
+
},
|
|
1841
|
+
getFormItemByField (field: string) {
|
|
1842
|
+
const $xeGantt = this
|
|
1843
|
+
|
|
1844
|
+
const $form = $xeGantt.$refs.refForm as VxeFormInstance
|
|
1845
|
+
if ($form) {
|
|
1846
|
+
return $form.getItemByField(field)
|
|
1847
|
+
}
|
|
1848
|
+
return null
|
|
1849
|
+
},
|
|
1780
1850
|
resetForm () {
|
|
1781
1851
|
const $xeGantt = this
|
|
1782
1852
|
|
|
@@ -2065,6 +2135,19 @@ export default /* define-vxe-component start */ defineVxeComponent({
|
|
|
2065
2135
|
}
|
|
2066
2136
|
return $xeGantt.$nextTick()
|
|
2067
2137
|
},
|
|
2138
|
+
getCriticalPath () {
|
|
2139
|
+
const $xeGantt = this
|
|
2140
|
+
const reactData = $xeGantt.reactData
|
|
2141
|
+
const internalData = $xeGantt.internalData
|
|
2142
|
+
|
|
2143
|
+
const { criticalRowIds, criticalLinks } = reactData
|
|
2144
|
+
const { criticalRowMaps } = internalData
|
|
2145
|
+
return {
|
|
2146
|
+
rowIds: criticalRowIds.slice(0),
|
|
2147
|
+
rows: Array.from(criticalRowMaps.values()),
|
|
2148
|
+
links: criticalLinks.slice(0)
|
|
2149
|
+
}
|
|
2150
|
+
},
|
|
2068
2151
|
/**
|
|
2069
2152
|
* 获取需要排除的高度
|
|
2070
2153
|
*/
|
|
@@ -2485,7 +2568,7 @@ export default /* define-vxe-component start */ defineVxeComponent({
|
|
|
2485
2568
|
// 处理插槽
|
|
2486
2569
|
formOpts.items.forEach((item) => {
|
|
2487
2570
|
XEUtils.each(item.slots, (func) => {
|
|
2488
|
-
if (!XEUtils.isFunction(func)) {
|
|
2571
|
+
if (func && !XEUtils.isFunction(func)) {
|
|
2489
2572
|
if (slots[func]) {
|
|
2490
2573
|
formSlots[func] = slots[func]
|
|
2491
2574
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import type { VxeGanttDefines, VxeGanttTaskType } from '../../../types'
|
|
2
1
|
import type { VxeTableDefines, VxeTablePropTypes } from 'vxe-table'
|
|
2
|
+
import type { VxeGanttDefines, VxeGanttTaskType } from '../../../types'
|
|
3
3
|
|
|
4
4
|
export function getRefElem (refEl: any) {
|
|
5
5
|
if (refEl) {
|
package/packages/ui/index.ts
CHANGED
|
@@ -100,6 +100,13 @@ setConfig({
|
|
|
100
100
|
taskBarSubviewConfig: {
|
|
101
101
|
// showOverview: false
|
|
102
102
|
},
|
|
103
|
+
taskBarMoveConfig: {
|
|
104
|
+
isLimitByLink: true
|
|
105
|
+
},
|
|
106
|
+
taskBarResizeConfig: {
|
|
107
|
+
minWidthSize: 0.5,
|
|
108
|
+
isLimitByLink: true
|
|
109
|
+
},
|
|
103
110
|
taskBarMoveTooltipConfig: {
|
|
104
111
|
enterable: true,
|
|
105
112
|
enterDelay: 0
|
|
@@ -15,6 +15,18 @@
|
|
|
15
15
|
height: 0;
|
|
16
16
|
}
|
|
17
17
|
.vxe-gantt-view--chart-row {
|
|
18
|
+
&.is--critical {
|
|
19
|
+
& > .vxe-gantt-view--chart-bar {
|
|
20
|
+
.vxe-gantt-view--chart-bar-content-wrapper {
|
|
21
|
+
border: var(--vxe-ui-gantt-view-task-line-width) solid var(--vxe-ui-gantt-view-bar-critical-path-line-color);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
& > .vxe-gantt-view--chart-custom-bar {
|
|
25
|
+
.vxe-gantt-view--chart-custom-bar-content-wrapper {
|
|
26
|
+
border: var(--vxe-ui-gantt-view-task-line-width) solid var(--vxe-ui-gantt-view-bar-critical-path-line-color);
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
}
|
|
18
30
|
&.row--pending {
|
|
19
31
|
.vxe-gantt-view--chart-bar {
|
|
20
32
|
color: var(--vxe-ui-font-disabled-color);
|
|
@@ -4,12 +4,29 @@
|
|
|
4
4
|
// 局部变量
|
|
5
5
|
.vxe-gantt {
|
|
6
6
|
--vxe-ui-gantt-current-split-bar-action-btn-offset-left: 0px;
|
|
7
|
+
--vxe-ui-gantt-current-font-size: var(--vxe-ui-font-size-default);
|
|
8
|
+
&.size--xlarge {
|
|
9
|
+
--vxe-ui-gantt-current-font-size: var(--vxe-ui-font-size-xlarge);
|
|
10
|
+
}
|
|
11
|
+
&.size--large {
|
|
12
|
+
--vxe-ui-gantt-current-font-size: var(--vxe-ui-font-size-large);
|
|
13
|
+
}
|
|
14
|
+
&.size--medium {
|
|
15
|
+
--vxe-ui-gantt-current-font-size: var(--vxe-ui-font-size-medium);
|
|
16
|
+
}
|
|
17
|
+
&.size--small {
|
|
18
|
+
--vxe-ui-gantt-current-font-size: var(--vxe-ui-font-size-small);
|
|
19
|
+
}
|
|
20
|
+
&.size--mini {
|
|
21
|
+
--vxe-ui-gantt-current-font-size: var(--vxe-ui-font-size-mini);
|
|
22
|
+
}
|
|
7
23
|
}
|
|
8
24
|
|
|
9
25
|
.vxe-gantt {
|
|
10
26
|
position: relative;
|
|
11
27
|
display: flex;
|
|
12
28
|
flex-direction: column;
|
|
29
|
+
font-size: var(--vxe-ui-gantt-current-font-size);
|
|
13
30
|
&.is--loading {
|
|
14
31
|
&:before {
|
|
15
32
|
content: "";
|
|
@@ -752,16 +769,3 @@
|
|
|
752
769
|
}
|
|
753
770
|
}
|
|
754
771
|
}
|
|
755
|
-
|
|
756
|
-
.vxe-gantt {
|
|
757
|
-
font-size: var(--vxe-ui-font-size-default);
|
|
758
|
-
&.size--medium {
|
|
759
|
-
font-size: var(--vxe-ui-font-size-medium);
|
|
760
|
-
}
|
|
761
|
-
&.size--small {
|
|
762
|
-
font-size: var(--vxe-ui-font-size-small);
|
|
763
|
-
}
|
|
764
|
-
&.size--mini {
|
|
765
|
-
font-size: var(--vxe-ui-font-size-mini);
|
|
766
|
-
}
|
|
767
|
-
}
|
package/styles/theme/base.scss
CHANGED
|
@@ -14,6 +14,8 @@
|
|
|
14
14
|
--vxe-ui-gantt-view-task-bar-background-color: var(--vxe-ui-font-primary-lighten-color);
|
|
15
15
|
--vxe-ui-gantt-view-task-bar-completed-background-color: var(--vxe-ui-font-primary-color);
|
|
16
16
|
--vxe-ui-gantt-view-task-bar-overview-background-color: var(--vxe-ui-font-disabled-color);
|
|
17
|
+
|
|
18
|
+
--vxe-ui-gantt-view-bar-critical-path-line-color: var(--vxe-ui-status-error-darken-color);
|
|
17
19
|
|
|
18
20
|
--vxe-ui-gantt-view-task-line-color: var(--vxe-ui-font-primary-color);
|
|
19
21
|
--vxe-ui-gantt-view-task-line-width: 2px;
|