UNPKG

vue-gantt-3

Version:

A gantt component for Vue 3

1 lines 19.3 kB
{"version":3,"file":"GanttView.vue.mjs","sources":["../../../../src/components/ganttView/GanttView.vue"],"sourcesContent":["<template>\n <div ref=\"ganttGanttView\" class=\"vg-gantt-view\">\n <GanttHeader\n ref=\"ganttHeaderRef\"\n :edgeSpacing=\"edgeSpacing\"\n :perHourSpacing=\"perHourSpacing\"\n :ganttMinDate=\"ganttMinDate\"\n :ganttViewWidth=\"ganttViewWidth\"\n :headerHeight=\"headerHeight\"\n :locale=\"locale\"\n :headerTextRender=\"headerTextRender\"\n :headerTipRender=\"headerTipRender\"\n ></GanttHeader>\n <ScrollBar ref=\"scrollBarRef\"\n :intercept-shift-scroll=\"true\"\n :alwayHorizontal=\"true\"\n @scroll=\"onScroll\"\n @wheel.prevent=\"onWheel\"\n @resize=\"onResize\"\n @shift-scroll.prevent=\"onShiftScroll\"\n @vertical-scroll-bar-show=\"onVerticalScrollBarShow\">\n <GanttBody\n ref=\"ganttBodyRef\"\n :rows=\"rows\"\n :rowNodeMap=\"rowNodeMap\"\n :rowHeight=\"rowHeight\"\n :edgeSpacing=\"edgeSpacing\"\n :perHourSpacing=\"perHourSpacing\"\n :ganttMinDate=\"ganttMinDate\"\n :ganttMaxDate=\"ganttMaxDate\"\n :rowBuffer=\"rowBuffer\"\n :ganttViewWidth=\"ganttViewWidth\"\n :visibleRowIds=\"visibleRowIds\"\n :styleOption=\"styleOption\"\n :timePointComp=\"timePointComp\"\n :timeLineRender=\"timeLineRender\"\n :timeLineRenderParams=\"timeLineRenderParams\"\n @update-min-date=\"updateMinDate\"\n @update-max-date=\"updateMaxDate\"\n ></GanttBody>\n </ScrollBar>\n </div>\n</template>\n<script lang=\"ts\" setup>\nimport ScrollBar from '../scrollbar/ScrollBar.vue';\nimport GanttHeader from './ganttHeader/GanttHeader.vue';\nimport type { RowData, ColDef, DefaultColDef, GanttRowNode, GanttStyleOption, TimeScale, GanttHeaderUnit } from '@/types';\nimport dayjs from 'dayjs';\nimport { ref, onBeforeMount, onMounted, watch, inject, provide } from 'vue';\nimport minMax from 'dayjs/plugin/minMax';\nimport GanttBody from './ganttBody/GanttBody.vue';\nimport { getRound, treeForEach } from '@/utils/common';\n\ndayjs.extend(minMax);\n\nexport interface Props {\n getRowId: (rowData: RowData) => string,\n columns: ColDef[],\n rows: RowData[],\n defaultCol?: DefaultColDef,\n rowHeight: number,\n headerHeight: number,\n rowBuffer: number,\n rowNodeMap: Map<string, GanttRowNode>,\n firstLevelRowNode: GanttRowNode[],\n visibleRowIds: string[],\n defaultPerHourSpacing?: number,\n defaultTimeScale?: TimeScale,\n styleOption?: GanttStyleOption,\n timePointComp?: any,\n locale?: string,\n timeLineRender?: any,\n timeLineRenderParams?: Record<string, any>,\n headerTextRender?: (date: dayjs.Dayjs, unit: GanttHeaderUnit) => string | number,\n headerTipRender?: (date: dayjs.Dayjs, unit: GanttHeaderUnit) => string,\n}\n\nconst props = withDefaults(defineProps<Props>(), {\n defaultPerHourSpacing: 0.1\n});\n\nconst emit = defineEmits<{\n (event: 'triggerTableViewScroll', options: ScrollToOptions, onWheel?: boolean): void,\n (event: 'ganttBodyResize', target: HTMLDivElement): void,\n (event: 'perHourSpacingChange', perHourSpacing: number): void,\n}>();\n\nconst ganttMinDate = ref<dayjs.Dayjs>(dayjs());\nconst ganttMaxDate = ref<dayjs.Dayjs | null>(null);\n\nconst edgeSpacing = ref(20); // Keep a 20px gap between the timeline and the display edge\nconst perHourSpacing = ref(props.defaultPerHourSpacing);\nconst ganttBodyRef = ref<InstanceType<typeof GanttBody>>();\nconst ganttHeaderRef = ref<InstanceType<typeof GanttHeader>>();\nconst scrollBarRef = ref<InstanceType<typeof ScrollBar>>();\nconst ganttGanttView = ref<HTMLDivElement>();\nconst scrollbarWrap = ref<HTMLDivElement>();\n\nconst perHourSpacingScale = 1.2;\nconst minPerHourSpacing = ref(0.007);\nconst maxPerHourSpacing = ref(1400);\nconst ganttViewWidth = ref(0);\nconst scrollFromTableView = ref(false);\nconst maxAndMindateCache = new Map<string, dayjs.Dayjs>();\n\nonBeforeMount(() => {\n updateMinAndMaxDate();\n updateGanttViewWidth();\n});\n\nonMounted(() => {\n scrollbarWrap.value = scrollBarRef.value?.$el.querySelector('.vg-scrollbar-wrap') as HTMLDivElement;\n});\n\nwatch([() => props.defaultPerHourSpacing, () => props.defaultTimeScale], ([currentPerHourSpacing, currentTimeScale]) => {\n if (currentTimeScale) {\n switch (currentTimeScale) {\n case 'day':\n perHourSpacing.value = 2;\n break;\n case 'week':\n perHourSpacing.value = 0.6;\n break;\n case 'month':\n perHourSpacing.value = 0.1;\n break;\n case 'quarter':\n perHourSpacing.value = 0.05;\n break;\n case 'year':\n perHourSpacing.value = 0.02;\n break;\n default:\n break;\n }\n } else {\n perHourSpacing.value = currentPerHourSpacing;\n }\n}, { immediate: true });\n\nconst getTopLevelRow = inject('getTopLevelRow') as (rowId: string, currentRowNodeMap: Map<string, GanttRowNode>) => GanttRowNode;\n\n/**\n * calculate the min and max date of the gantt\n * @param excludeRowIds\n * @param freshStartDate\n * @param freshEndDate\n */\nconst getGanttMinAndMaxDate = (excludeRowIds: string[] = [], freshStartDate = true, freshEndDate = true) => {\n const isSingleExclude = excludeRowIds.length === 1;\n if (isSingleExclude) {\n if (maxAndMindateCache.has('minStartDate') && maxAndMindateCache.has('maxEndDate')) {\n return {\n minStartDate: maxAndMindateCache.get('minStartDate'),\n maxEndDate: maxAndMindateCache.get('maxEndDate')\n };\n }\n }\n const excludeRowIdSet = new Set(excludeRowIds);\n const excludeFirstLevelRowId = excludeRowIds.map((rowId) => getTopLevelRow(rowId, props.rowNodeMap).id);\n const excludeFirstLevelRowIdSet = new Set(excludeFirstLevelRowId);\n const needFirstLevelRowNode: GanttRowNode[] = [];\n const excludeFirstLevelRowNode: GanttRowNode[] = [];\n for (let rowNode of props.firstLevelRowNode) {\n if (excludeFirstLevelRowIdSet.has(rowNode.id)) {\n excludeFirstLevelRowNode.push(rowNode);\n } else {\n needFirstLevelRowNode.push(rowNode);\n }\n }\n\n const { minStartDate, maxEndDate } = getMinAndMaxDate(needFirstLevelRowNode, freshStartDate, freshEndDate);\n let allMinStartDates: dayjs.Dayjs[] = [];\n let allMaxEndDates: dayjs.Dayjs[] = [];\n\n if (minStartDate) {\n allMinStartDates.push(minStartDate);\n }\n if (maxEndDate) {\n allMaxEndDates.push(maxEndDate);\n }\n\n treeForEach(excludeFirstLevelRowNode, (rowNode) => {\n if (!rowNode.hasChildren && !excludeRowIdSet.has(rowNode.id)) {\n rowNode.startDate && allMinStartDates.push(rowNode.startDate);\n rowNode.endDate && allMaxEndDates.push(rowNode.endDate);\n }\n });\n\n const finalMinStartDate = dayjs.min(allMinStartDates);\n const finalMaxEndDate = dayjs.max(allMaxEndDates);\n if (isSingleExclude && finalMinStartDate && finalMaxEndDate) {\n maxAndMindateCache.set('minStartDate', finalMinStartDate);\n maxAndMindateCache.set('maxEndDate', finalMaxEndDate);\n }\n return {\n minStartDate: finalMinStartDate,\n maxEndDate: finalMaxEndDate\n };\n};\n\nprovide(\n 'getGanttMinAndMaxDate',\n getGanttMinAndMaxDate\n);\n\nconst clearDateCache = () => {\n maxAndMindateCache.clear();\n};\n\nprovide(\n 'clearDateCache',\n clearDateCache\n);\n\nconst updateMinAndMaxDate = () => {\n const { minStartDate, maxEndDate } = getMinAndMaxDate(props.firstLevelRowNode);\n if (minStartDate) {\n ganttMinDate.value = minStartDate;\n }\n if (maxEndDate) {\n ganttMaxDate.value = maxEndDate;\n }\n};\n\nconst updateMinDate = (minDate: dayjs.Dayjs) => {\n ganttMinDate.value = minDate;\n};\n\nconst updateMaxDate = (maxDate: dayjs.Dayjs) => {\n ganttMaxDate.value = maxDate;\n};\n\n/**\n * calculate the width of the gantt by the min and max date\n */\nconst updateGanttViewWidth = () => {\n const diffHour = ganttMaxDate.value?.diff(ganttMinDate.value, 'hour', true) || 0;\n if (diffHour > 0) {\n ganttViewWidth.value = getRound(diffHour * perHourSpacing.value + edgeSpacing.value * 2);\n }\n\n // browser max width is 16777200\n maxPerHourSpacing.value = Math.floor((16777200 - edgeSpacing.value * 2) / diffHour);\n};\n\nwatch([perHourSpacing, ganttMinDate, ganttMaxDate, edgeSpacing], updateGanttViewWidth);\n\n/**\n * calculate the min and max date from the rowNodes\n * @param expectRowNodes\n * @param freshStartDate\n * @param freshEndDate\n */\nconst getMinAndMaxDate = (expectRowNodes: GanttRowNode[], freshStartDate = true, freshEndDate = true) => {\n const startDateArr: dayjs.Dayjs[] = [];\n const endDateArr: dayjs.Dayjs[] = [];\n if (freshStartDate) {\n for (let rowNode of expectRowNodes) {\n rowNode.startDate && startDateArr.push(rowNode.startDate);\n }\n }\n\n if (freshEndDate) {\n for (let rowNode of expectRowNodes) {\n rowNode.endDate && endDateArr.push(rowNode.endDate);\n }\n }\n\n return {\n minStartDate: dayjs.min(startDateArr),\n maxEndDate: dayjs.max(endDateArr)\n };\n};\n\n/**\n * trigger when rowNode change\n * @param param0 addedRowNodes is new, deletedRowNodes is old, updatedRowNodes include new and old\n * @param freshRowNodes\n */\nconst updateMinAndMaxDateByChangeRowNode = ({ addedRowNodes = [], deletedRowNodes = [], updatedRowNodes = [] }:\n{addedRowNodes?: GanttRowNode[], deletedRowNodes?: GanttRowNode[], updatedRowNodes?: GanttRowNode[]}, freshRowNodes: GanttRowNode[]) => {\n let freshStartDate = false;\n let freshEndDate = false;\n for (let updatedRowNode of updatedRowNodes) {\n addedRowNodes.push({\n ...updatedRowNode,\n });\n const oldStartDate = updatedRowNode.oldStartDate;\n const oldEndDate = updatedRowNode.oldEndDate;\n deletedRowNodes.push({\n ...updatedRowNode,\n startDate: oldStartDate!,\n endDate: oldEndDate!\n });\n }\n\n for (let deletedRowNode of deletedRowNodes) {\n if (!freshStartDate && deletedRowNode.startDate?.isSame(ganttMinDate.value)) {\n freshStartDate = true;\n }\n if (!freshEndDate && deletedRowNode.endDate?.isSame(ganttMaxDate.value)) {\n freshEndDate = true;\n }\n }\n\n if (freshStartDate || freshEndDate) {\n const { minStartDate, maxEndDate } = getMinAndMaxDate(freshRowNodes, freshStartDate, freshEndDate);\n if (minStartDate) {\n ganttMinDate.value = minStartDate;\n }\n if (maxEndDate) {\n ganttMaxDate.value = maxEndDate;\n }\n }\n\n for (let addedRowNode of addedRowNodes) {\n if (addedRowNode.startDate && addedRowNode.startDate.isBefore(ganttMinDate.value)) {\n ganttMinDate.value = addedRowNode.startDate;\n }\n if (addedRowNode.endDate && (!ganttMaxDate.value || addedRowNode.endDate.isAfter(ganttMaxDate.value))) {\n ganttMaxDate.value = addedRowNode.endDate;\n }\n }\n\n};\n\nconst onScroll = ({ scrollTop, scrollLeft }: {scrollTop: number, scrollLeft: number}) => {\n if (scrollFromTableView.value) {\n scrollFromTableView.value = false;\n } else {\n emit('triggerTableViewScroll', { top: scrollTop });\n }\n if (ganttBodyRef.value) {\n ganttBodyRef.value.onScroll({ scrollTop, scrollLeft });\n }\n if (ganttHeaderRef.value) {\n ganttHeaderRef.value.onScroll({ scrollLeft });\n }\n};\n\nconst onWheel = (e: WheelEvent) => {\n if (!scrollbarWrap.value) return;\n if (Math.abs(e.deltaY) < 3) return; // prevent the touchpad from scrolling continuously\n const scrollSpeed = 100;\n const scrollDistance = e.deltaY > 0 ? scrollSpeed : -scrollSpeed;\n const scrollTop = scrollbarWrap.value?.scrollTop + scrollDistance;\n scrollBarRef.value?.triggerScrollFromOutSide({ top: scrollTop });\n scrollFromTableView.value = true;\n emit('triggerTableViewScroll', { top: scrollTop }, true);\n};\n\nconst onResize = (target: HTMLDivElement) => {\n if (ganttBodyRef.value) {\n ganttBodyRef.value.onResize();\n }\n if (ganttHeaderRef.value) {\n ganttHeaderRef.value.onResize();\n }\n emit('ganttBodyResize', target);\n};\n\nconst onShiftScroll = (e: WheelEvent) => {\n if (Math.abs(e.deltaY) < 3) return;\n if (e.deltaY > 0) {\n const newPerHourSpacing = perHourSpacing.value / perHourSpacingScale;\n perHourSpacing.value = Math.max(newPerHourSpacing, minPerHourSpacing.value);\n } else if (e.deltaY < 0) {\n const newPerHourSpacing = perHourSpacing.value * perHourSpacingScale;\n perHourSpacing.value = Math.min(newPerHourSpacing, maxPerHourSpacing.value);\n }\n emit('perHourSpacingChange', perHourSpacing.value);\n};\n\nconst onVerticalScrollBarShow = ({ show, scrollbarWidth }: {show: boolean, scrollbarWidth: number}) => {\n if (ganttHeaderRef.value) {\n ganttHeaderRef.value.updateGanttHeaderWidth(show, scrollbarWidth);\n }\n};\n\nconst scrollTo = (options: ScrollToOptions) => {\n scrollFromTableView.value = true;\n // use triggerScrollFromOutSide to prevent the tableView from scrolling too fast and causing the timelineView to white screen\n scrollBarRef.value?.triggerScrollFromOutSide(options);\n};\n\n/**\n * trigger by user to fresh time lines\n * @param rowNodes\n */\nconst freshTimeLines = (rowNodes: GanttRowNode[]) => {\n if (ganttBodyRef.value) {\n ganttBodyRef.value.freshTimeLines(rowNodes);\n }\n};\n\ndefineExpose({\n scrollTo,\n updateMinAndMaxDateByChangeRowNode,\n freshTimeLines\n});\n\n</script>\n<style lang=\"scss\">\n.vg-gantt-view {\n display: flex;\n flex-direction: column;\n height: 100%;\n overflow: hidden;\n .vg-scrollbar {\n flex: 1;\n }\n}\n</style>"],"names":[],"mappings":"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"}