vue-gantt-3
Version:
A gantt component for Vue 3
1 lines • 16 kB
Source Map (JSON)
{"version":3,"file":"useTimeLineStretch.mjs","sources":["../../../../../../src/components/ganttView/ganttBody/ganttTimeLineView/useTimeLineStretch.ts"],"sourcesContent":["import { inject, triggerRef } from 'vue';\nimport type { Ref, ShallowRef, ComputedRef } from 'vue';\nimport type { GanttRowNode, VisibleTimeLine, TimeLineNode } from '@/types';\nimport dayjs from 'dayjs';\nimport { getRound } from '@/utils/common';\n\nexport const useTimeLineStretch = ({\n edgeSpacing,\n ganttViewWidth,\n rowNodeMap,\n movingTimeLineRowId,\n movingTimeLine,\n timeLineMoving,\n visibleTimeLineMap,\n disableStretch,\n closeEdgeScroll,\n sortTimeLineNodes,\n mergeOverlapTimeLine,\n freshVisibleTimeLines,\n getDiffSecondByDistance,\n getDistanceByDiffDate,\n emitUpdateMinDate,\n emitUpdateMaxDate,\n updateParentTimeLine\n}: {\n edgeSpacing: number,\n ganttViewWidth: Ref<number>,\n rowNodeMap: Ref<Map<string, GanttRowNode>, Map<string, GanttRowNode>>,\n movingTimeLineRowId: Ref<string>,\n movingTimeLine: Ref<VisibleTimeLine | null>,\n timeLineMoving: Ref<boolean>,\n visibleTimeLineMap: ShallowRef<Map<string, VisibleTimeLine[]>, Map<string, VisibleTimeLine[]>>,\n disableStretch: ComputedRef<boolean | undefined>,\n closeEdgeScroll: (perMoveSpacing: number, callBack: (moveSpacing: number) => any) => void\n sortTimeLineNodes: (timeLineNodes: TimeLineNode[]) => void,\n mergeOverlapTimeLine: (timeLineNodes: TimeLineNode[]) => TimeLineNode[],\n freshVisibleTimeLines: (freshAll?: boolean) => void\n getDiffSecondByDistance: (distance: number, startDate: dayjs.Dayjs) => dayjs.Dayjs,\n getDistanceByDiffDate: (startDate: dayjs.Dayjs, endDate: dayjs.Dayjs) => number,\n emitUpdateMinDate: (date: dayjs.Dayjs) => void,\n emitUpdateMaxDate: (date: dayjs.Dayjs) => void,\n updateParentTimeLine: (rowId: string) => void\n}) => {\n const wrapRef = inject('wrapRef') as Ref<HTMLDivElement | undefined>;\n const freshRowNodeDateByTimeLine = inject('freshRowNodeDateByTimeLine') as (rowId: string) => void;\n const getGanttMinAndMaxDate = inject('getGanttMinAndMaxDate') as (excludeRowIds?: string[], freshStartDate?: boolean, freshEndDate?: boolean)\n => { minStartDate: dayjs.Dayjs | null, maxEndDate: dayjs.Dayjs | null };\n const timeLineStretchChange = inject('timeLineStretchChange') as (rowId: string, timeLineIds: string[], startDate: dayjs.Dayjs | null, endDate: dayjs.Dayjs | null) => void;\n const clearDateCache = inject('clearDateCache') as () => void;\n\n /**\n * handle time line stretch\n * @param e\n * @param timeLine\n * @param rowId\n * @param direction\n */\n const startTimeLineStretch = (e: MouseEvent, timeLine: VisibleTimeLine, rowId: string, direction: 'left' | 'right') => {\n if (disableStretch.value || timeLine.disableStretch) return;\n let lastX = e.clientX;\n const oldWidth = timeLine.width;\n const minWidth = 4;\n const wrapWidth = wrapRef.value!.offsetWidth;\n const currentRowNode = rowNodeMap.value.get(rowId);\n let invalidDistance = 0;\n let startScrollX = 0;\n movingTimeLine.value = timeLine;\n movingTimeLineRowId.value = rowId;\n e.stopPropagation();\n const onMouseMove = (event: MouseEvent) => {\n let currentX = event.clientX;\n const diffX = currentX - lastX;\n\n // keep stretch if timeline width is less than minWidth, it will produce invalid distance,\n // then stretch on reverse direction, it will reduce invalid distance, stretch will be effected until invalid distance is 0\n const perInvalidDistance = calcPerInvalidDistance(timeLine.width, diffX, minWidth, direction);\n if (invalidDistance === 0) {\n timeLineStretch(timeLine, rowId, diffX, minWidth, direction);\n }\n const nextInvalidDistance = invalidDistance + perInvalidDistance;\n if ((nextInvalidDistance >= 0 && direction === 'left')\n || (nextInvalidDistance <= 0 && direction === 'right')) {\n invalidDistance += perInvalidDistance;\n } else if ((invalidDistance > 0 && nextInvalidDistance < 0 && direction === 'left')\n || (invalidDistance < 0 && nextInvalidDistance > 0 && direction === 'right')) {\n timeLineStretch(timeLine, rowId, nextInvalidDistance, minWidth, direction);\n invalidDistance = 0;\n }\n\n const scrollLeft = wrapRef.value!.scrollLeft;\n const scrollDistance = 10;\n if ((direction === 'left' && timeLine.translateX - scrollLeft <= edgeSpacing)\n || (direction === 'right' && timeLine.translateX + timeLine.width - scrollLeft <= edgeSpacing)) {\n if (diffX < 0) {\n if (!timeLineMoving.value) {\n timeLineMoving.value = true;\n startScrollX = lastX;\n closeEdgeScroll(-scrollDistance, (moveSpacing) => {\n if (direction === 'right' && timeLine.width - scrollDistance < minWidth) {\n timeLineMoving.value = false;\n invalidDistance -= minWidth - timeLine.width + scrollDistance;\n }\n timeLineStretch(timeLine, rowId, moveSpacing, minWidth, direction);\n });\n }\n } else if (currentX >= startScrollX) {\n timeLineMoving.value = false;\n }\n\n } else if ((direction === 'right' && scrollLeft + wrapWidth <= timeLine.translateX + timeLine.width + edgeSpacing)\n || (direction === 'left' && scrollLeft + wrapWidth <= timeLine.translateX + edgeSpacing)) {\n if (diffX > 0) {\n if (!timeLineMoving.value) {\n timeLineMoving.value = true;\n startScrollX = lastX;\n closeEdgeScroll(scrollDistance, (moveSpacing) => {\n if (direction === 'left' && timeLine.width - scrollDistance < minWidth) {\n timeLineMoving.value = false;\n invalidDistance += minWidth - timeLine.width + scrollDistance;\n }\n timeLineStretch(timeLine, rowId, moveSpacing, minWidth, direction);\n });\n }\n } else if (currentX <= startScrollX) {\n timeLineMoving.value = false;\n }\n\n } else {\n timeLineMoving.value = false;\n }\n lastX = currentX;\n\n };\n const onMouseUp = () => {\n timeLineMoving.value = false;\n movingTimeLine.value = null;\n movingTimeLineRowId.value = '';\n clearDateCache();\n if (timeLine.width !== oldWidth) {\n // update row node date\n freshRowNodeDateByTimeLine(rowId);\n if (currentRowNode?.timeLineNodes) {\n // if time line overlap, merge them\n sortTimeLineNodes(currentRowNode.timeLineNodes);\n currentRowNode.timeLineNodes = mergeOverlapTimeLine(currentRowNode.timeLineNodes);\n\n // if timeline is a merge node, update all merged nodes' date\n onTimeLineStretchChange(rowId, timeLine, direction);\n\n // fresh visible time lines\n visibleTimeLineMap.value.delete(rowId);\n freshVisibleTimeLines(false);\n }\n }\n window.removeEventListener('mousemove', onMouseMove);\n window.removeEventListener('mouseup', onMouseUp);\n };\n\n window.addEventListener('mousemove', onMouseMove);\n window.addEventListener('mouseup', onMouseUp);\n };\n\n /**\n * calculate time line position, date and gantt min and max date\n * @param timeLine\n * @param rowId\n * @param distance\n * @param minWidth\n * @param direction\n * @returns\n */\n const timeLineStretch = (timeLine: VisibleTimeLine, rowId: string, distance: number, minWidth: number, direction: 'left' | 'right') => {\n const oldWidth = timeLine.width;\n if (direction === 'left') {\n timeLine.width -= distance;\n } else {\n timeLine.width += distance;\n }\n if (timeLine.width < minWidth) {\n timeLine.width = minWidth;\n }\n const diffWidth = oldWidth - timeLine.width;\n if (direction === 'left') {\n const nextStartDate = getDiffSecondByDistance(diffWidth, timeLine.startDate);\n timeLine.timeLineNode.startDate = nextStartDate;\n timeLine.startDate = nextStartDate;\n if (getRound(timeLine.translateX) === edgeSpacing && diffWidth > 0) {\n const { minStartDate } = getGanttMinAndMaxDate([rowId], true, false);\n if (!minStartDate || nextStartDate.isBefore(minStartDate)) {\n emitUpdateMinDate(nextStartDate);\n timeLine.translateX = edgeSpacing;\n updateParentTimeLine(rowId);\n return;\n } else if (nextStartDate.isAfter(minStartDate) || nextStartDate.isSame(minStartDate)) {\n timeLine.translateX += getDistanceByDiffDate(minStartDate, nextStartDate);\n emitUpdateMinDate(minStartDate);\n updateParentTimeLine(rowId);\n return;\n }\n }\n timeLine.translateX += diffWidth;\n } else {\n const nextEndDate = getDiffSecondByDistance(-diffWidth, timeLine.endDate);\n timeLine.timeLineNode.endDate = nextEndDate;\n timeLine.endDate = nextEndDate;\n if (getRound(timeLine.translateX + oldWidth + edgeSpacing) === getRound(ganttViewWidth.value) && diffWidth > 0) {\n const { maxEndDate } = getGanttMinAndMaxDate([rowId], false, true);\n if (!maxEndDate || nextEndDate.isAfter(maxEndDate)) {\n emitUpdateMaxDate(nextEndDate);\n updateParentTimeLine(rowId);\n return;\n } else if (nextEndDate.isBefore(maxEndDate) || nextEndDate.isSame(maxEndDate)) {\n emitUpdateMaxDate(maxEndDate);\n }\n }\n }\n if (timeLine.translateX < edgeSpacing) {\n emitUpdateMinDate(timeLine.startDate);\n timeLine.translateX = edgeSpacing;\n } else if (timeLine.translateX + timeLine.width + edgeSpacing > ganttViewWidth.value) {\n emitUpdateMaxDate(timeLine.endDate);\n }\n updateParentTimeLine(rowId);\n triggerRef(visibleTimeLineMap);\n };\n\n const calcPerInvalidDistance = (timeLineWidth: number, distance: number, minWidth: number, direction: 'left' | 'right') => {\n if (direction === 'left') {\n return minWidth - timeLineWidth + distance;\n } else {\n return timeLineWidth + distance - minWidth;\n }\n };\n\n /**\n * update merged time line nodes' date, and notice user\n * @param rowId\n * @param timeLine\n * @param direction\n */\n const onTimeLineStretchChange = (rowId: string, timeLine: VisibleTimeLine, direction: 'left' | 'right') => {\n const timeLineNode = timeLine.timeLineNode;\n const timeLineIds: string[] = [timeLineNode.id];\n const finalStartDate = direction === 'left' ? timeLineNode.startDate : null;\n const finalEndDate = direction === 'right' ? timeLineNode.endDate : null;\n\n if (timeLineNode.isMerge) {\n const mergedTimeLineNodes = timeLineNode.mergedTimeLineNodes;\n for (let mergedTimeLineNode of mergedTimeLineNodes!) {\n if (direction === 'left') {\n if (mergedTimeLineNode.startDate.isBefore(timeLineNode.startDate)) {\n timeLineIds.push(mergedTimeLineNode.id);\n mergedTimeLineNode.startDate = timeLineNode.startDate;\n }\n } else {\n if (mergedTimeLineNode.endDate.isAfter(timeLineNode.endDate)) {\n timeLineIds.push(mergedTimeLineNode.id);\n mergedTimeLineNode.endDate = timeLineNode.endDate;\n }\n }\n }\n }\n timeLineStretchChange(rowId, timeLineIds, finalStartDate, finalEndDate);\n };\n return {\n startTimeLineStretch\n };\n};"],"names":[],"mappings":";;AAMO,MAAM,qBAAqB,CAAC;AAAA,EACjC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAkBM;AACE,QAAA,UAAU,OAAO,SAAS;AAC1B,QAAA,6BAA6B,OAAO,4BAA4B;AAChE,QAAA,wBAAwB,OAAO,uBAAuB;AAEtD,QAAA,wBAAwB,OAAO,uBAAuB;AACtD,QAAA,iBAAiB,OAAO,gBAAgB;AAS9C,QAAM,uBAAuB,CAAC,GAAe,UAA2B,OAAe,cAAgC;AACjH,QAAA,eAAe,SAAS,SAAS,eAAgB;AACrD,QAAI,QAAQ,EAAE;AACd,UAAM,WAAW,SAAS;AAC1B,UAAM,WAAW;AACX,UAAA,YAAY,QAAQ,MAAO;AACjC,UAAM,iBAAiB,WAAW,MAAM,IAAI,KAAK;AACjD,QAAI,kBAAkB;AACtB,QAAI,eAAe;AACnB,mBAAe,QAAQ;AACvB,wBAAoB,QAAQ;AAC5B,MAAE,gBAAgB;AACZ,UAAA,cAAc,CAAC,UAAsB;AACzC,UAAI,WAAW,MAAM;AACrB,YAAM,QAAQ,WAAW;AAIzB,YAAM,qBAAqB,uBAAuB,SAAS,OAAO,OAAO,UAAU,SAAS;AAC5F,UAAI,oBAAoB,GAAG;AACzB,wBAAgB,UAAU,OAAO,OAAO,UAAU,SAAS;AAAA,MAAA;AAE7D,YAAM,sBAAsB,kBAAkB;AAC9C,UAAK,uBAAuB,KAAK,cAAc,UAC3C,uBAAuB,KAAK,cAAc,SAAU;AACnC,2BAAA;AAAA,MACT,WAAA,kBAAkB,KAAK,sBAAsB,KAAK,cAAc,UACxE,kBAAkB,KAAK,sBAAsB,KAAK,cAAc,SAAU;AAC5E,wBAAgB,UAAU,OAAO,qBAAqB,UAAU,SAAS;AACvD,0BAAA;AAAA,MAAA;AAGd,YAAA,aAAa,QAAQ,MAAO;AAClC,YAAM,iBAAiB;AACvB,UAAK,cAAc,UAAU,SAAS,aAAa,cAAc,eAC7D,cAAc,WAAW,SAAS,aAAa,SAAS,QAAQ,cAAc,aAAc;AAC9F,YAAI,QAAQ,GAAG;AACT,cAAA,CAAC,eAAe,OAAO;AACzB,2BAAe,QAAQ;AACR,2BAAA;AACC,4BAAA,KAAiB,CAAC,gBAAgB;AAChD,kBAAI,cAAc,WAAW,SAAS,QAAQ,iBAAiB,UAAU;AACvE,+BAAe,QAAQ;AACJ,mCAAA,WAAW,SAAS,QAAQ;AAAA,cAAA;AAEjD,8BAAgB,UAAU,OAAO,aAAa,UAAU,SAAS;AAAA,YAAA,CAClE;AAAA,UAAA;AAAA,QACH,WACS,YAAY,cAAc;AACnC,yBAAe,QAAQ;AAAA,QAAA;AAAA,MACzB,WAEU,cAAc,WAAW,aAAa,aAAa,SAAS,aAAa,SAAS,QAAQ,eACjG,cAAc,UAAU,aAAa,aAAa,SAAS,aAAa,aAAc;AACzF,YAAI,QAAQ,GAAG;AACT,cAAA,CAAC,eAAe,OAAO;AACzB,2BAAe,QAAQ;AACR,2BAAA;AACC,4BAAA,gBAAgB,CAAC,gBAAgB;AAC/C,kBAAI,cAAc,UAAU,SAAS,QAAQ,iBAAiB,UAAU;AACtE,+BAAe,QAAQ;AACJ,mCAAA,WAAW,SAAS,QAAQ;AAAA,cAAA;AAEjD,8BAAgB,UAAU,OAAO,aAAa,UAAU,SAAS;AAAA,YAAA,CAClE;AAAA,UAAA;AAAA,QACH,WACS,YAAY,cAAc;AACnC,yBAAe,QAAQ;AAAA,QAAA;AAAA,MACzB,OAEK;AACL,uBAAe,QAAQ;AAAA,MAAA;AAEjB,cAAA;AAAA,IAEV;AACA,UAAM,YAAY,MAAM;AACtB,qBAAe,QAAQ;AACvB,qBAAe,QAAQ;AACvB,0BAAoB,QAAQ;AACb,qBAAA;AACX,UAAA,SAAS,UAAU,UAAU;AAE/B,mCAA2B,KAAK;AAChC,YAAI,iDAAgB,eAAe;AAEjC,4BAAkB,eAAe,aAAa;AAC/B,yBAAA,gBAAgB,qBAAqB,eAAe,aAAa;AAGxD,kCAAA,OAAO,UAAU,SAAS;AAG/B,6BAAA,MAAM,OAAO,KAAK;AACrC,gCAAsB,KAAK;AAAA,QAAA;AAAA,MAC7B;AAEK,aAAA,oBAAoB,aAAa,WAAW;AAC5C,aAAA,oBAAoB,WAAW,SAAS;AAAA,IACjD;AAEO,WAAA,iBAAiB,aAAa,WAAW;AACzC,WAAA,iBAAiB,WAAW,SAAS;AAAA,EAC9C;AAWA,QAAM,kBAAkB,CAAC,UAA2B,OAAe,UAAkB,UAAkB,cAAgC;AACrI,UAAM,WAAW,SAAS;AAC1B,QAAI,cAAc,QAAQ;AACxB,eAAS,SAAS;AAAA,IAAA,OACb;AACL,eAAS,SAAS;AAAA,IAAA;AAEhB,QAAA,SAAS,QAAQ,UAAU;AAC7B,eAAS,QAAQ;AAAA,IAAA;AAEb,UAAA,YAAY,WAAW,SAAS;AACtC,QAAI,cAAc,QAAQ;AACxB,YAAM,gBAAgB,wBAAwB,WAAW,SAAS,SAAS;AAC3E,eAAS,aAAa,YAAY;AAClC,eAAS,YAAY;AACrB,UAAI,SAAS,SAAS,UAAU,MAAM,eAAe,YAAY,GAAG;AAC5D,cAAA,EAAE,iBAAiB,sBAAsB,CAAC,KAAK,GAAG,MAAM,KAAK;AACnE,YAAI,CAAC,gBAAgB,cAAc,SAAS,YAAY,GAAG;AACzD,4BAAkB,aAAa;AAC/B,mBAAS,aAAa;AACtB,+BAAqB,KAAK;AAC1B;AAAA,QAAA,WACS,cAAc,QAAQ,YAAY,KAAK,cAAc,OAAO,YAAY,GAAG;AAC3E,mBAAA,cAAc,sBAAsB,cAAc,aAAa;AACxE,4BAAkB,YAAY;AAC9B,+BAAqB,KAAK;AAC1B;AAAA,QAAA;AAAA,MACF;AAEF,eAAS,cAAc;AAAA,IAAA,OAClB;AACL,YAAM,cAAc,wBAAwB,CAAC,WAAW,SAAS,OAAO;AACxE,eAAS,aAAa,UAAU;AAChC,eAAS,UAAU;AACf,UAAA,SAAS,SAAS,aAAa,WAAW,WAAW,MAAM,SAAS,eAAe,KAAK,KAAK,YAAY,GAAG;AACxG,cAAA,EAAE,eAAe,sBAAsB,CAAC,KAAK,GAAG,OAAO,IAAI;AACjE,YAAI,CAAC,cAAc,YAAY,QAAQ,UAAU,GAAG;AAClD,4BAAkB,WAAW;AAC7B,+BAAqB,KAAK;AAC1B;AAAA,QAAA,WACS,YAAY,SAAS,UAAU,KAAK,YAAY,OAAO,UAAU,GAAG;AAC7E,4BAAkB,UAAU;AAAA,QAAA;AAAA,MAC9B;AAAA,IACF;AAEE,QAAA,SAAS,aAAa,aAAa;AACrC,wBAAkB,SAAS,SAAS;AACpC,eAAS,aAAa;AAAA,IAAA,WACb,SAAS,aAAa,SAAS,QAAQ,cAAc,eAAe,OAAO;AACpF,wBAAkB,SAAS,OAAO;AAAA,IAAA;AAEpC,yBAAqB,KAAK;AAC1B,eAAW,kBAAkB;AAAA,EAC/B;AAEA,QAAM,yBAAyB,CAAC,eAAuB,UAAkB,UAAkB,cAAgC;AACzH,QAAI,cAAc,QAAQ;AACxB,aAAO,WAAW,gBAAgB;AAAA,IAAA,OAC7B;AACL,aAAO,gBAAgB,WAAW;AAAA,IAAA;AAAA,EAEtC;AAQA,QAAM,0BAA0B,CAAC,OAAe,UAA2B,cAAgC;AACzG,UAAM,eAAe,SAAS;AACxB,UAAA,cAAwB,CAAC,aAAa,EAAE;AAC9C,UAAM,iBAAiB,cAAc,SAAS,aAAa,YAAY;AACvE,UAAM,eAAe,cAAc,UAAU,aAAa,UAAU;AAEpE,QAAI,aAAa,SAAS;AACxB,YAAM,sBAAsB,aAAa;AACzC,eAAS,sBAAsB,qBAAsB;AACnD,YAAI,cAAc,QAAQ;AACxB,cAAI,mBAAmB,UAAU,SAAS,aAAa,SAAS,GAAG;AACrD,wBAAA,KAAK,mBAAmB,EAAE;AACtC,+BAAmB,YAAY,aAAa;AAAA,UAAA;AAAA,QAC9C,OACK;AACL,cAAI,mBAAmB,QAAQ,QAAQ,aAAa,OAAO,GAAG;AAChD,wBAAA,KAAK,mBAAmB,EAAE;AACtC,+BAAmB,UAAU,aAAa;AAAA,UAAA;AAAA,QAC5C;AAAA,MACF;AAAA,IACF;AAEoB,0BAAA,OAAO,aAAa,gBAAgB,YAAY;AAAA,EACxE;AACO,SAAA;AAAA,IACL;AAAA,EACF;AACF;"}