vue-gantt-3
Version:
A gantt component for Vue 3
1 lines • 12.7 kB
Source Map (JSON)
{"version":3,"file":"Gantt.vue.mjs","sources":["../../src/Gantt.vue"],"sourcesContent":["<template>\n <div ref=\"vGanttRef\" class=\"vue-gantt-3\" @contextmenu.prevent=\"onContextmenu\">\n <ExpandableBox :initWidth=\"defaultTableViewWidth\" :maxWidth=\"maxTableViewWidth\">\n <TableView\n ref=\"tableViewRef\"\n :getRowId=\"getRowId\"\n :columns=\"columns\"\n :defaultCol=\"defaultCol\"\n :rowHeight=\"rowHeightRef\"\n :headerHeight=\"headerHeight\"\n :rowBuffer=\"rowBuffer\"\n :rowSelection=\"rowSelectionRef\"\n :rows=\"rowDataList\"\n :rowNodeMap=\"rowNodeMap\"\n :getEmptyRows=\"getEmptyRows\"\n @trigger-gantt-view-scroll=\"triggerGanttViewScroll\"\n @view-port-changed=\"onViewPortChanged\"\n @cell-double-clicked=\"onCellDoubleClicked\"\n >\n </TableView>\n </ExpandableBox>\n <GanttView\n ref=\"ganttViewRef\"\n :getRowId=\"getRowId\"\n :columns=\"columns\"\n :rows=\"rowsRef\"\n :defaultCol=\"defaultCol\"\n :rowHeight=\"rowHeightRef\"\n :headerHeight=\"headerHeight\"\n :rowBuffer=\"rowBuffer\"\n :rowNodeMap=\"rowNodeMap\"\n :firstLevelRowNode=\"firstLevelRowNode\"\n :visibleRowIds=\"visibleRowIds\"\n :styleOption=\"styleOption\"\n :timePointComp=\"timePointComp\"\n :defaultPerHourSpacing=\"defaultPerHourSpacing\"\n :defaultTimeScale=\"defaultTimeScale\"\n :locale=\"locale\"\n :timeLineRender=\"timeLineRender\"\n :timeLineRenderParams=\"timeLineRenderParams\"\n :headerTextRender=\"headerTextRender\"\n :headerTipRender=\"headerTipRender\"\n @trigger-table-view-scroll=\"triggerTableViewScroll\"\n @gantt-body-resize=\"onGanttBodyResize\"\n @perHourSpacingChange=\"perHourSpacingChange\"\n ></GanttView>\n </div>\n</template>\n<script lang=\"ts\" setup>\nimport TableView from \"./components/tableView/TableView.vue\";\nimport GanttView from \"./components/ganttView/GanttView.vue\";\nimport type { RowData, ColDef, DefaultColDef, GanttRowNode, GanttStyleOption, TimePoint, MovedTimeLineData, TimeScale, GanttHeaderUnit } from '@/types';\nimport { ref, provide, toRef } from 'vue';\nimport ExpandableBox from './components/common/ExpandableBox.vue';\nimport dayjs from 'dayjs';\nimport minMax from 'dayjs/plugin/minMax';\nimport { useGanttRowNode } from './composables/useGanttRowNode';\nimport { useGanttSelect } from './composables/useGanttSelect';\nimport { useGanttExpand } from './composables/useGanttExpand';\n\ndayjs.extend(minMax);\n\nexport interface GanttOption {\n getRowId: (rowData: RowData) => string,\n columns?: ColDef[],\n rows?: RowData[],\n getEmptyRows?: (count: number) => RowData[],\n headerTextRender?: (date: dayjs.Dayjs, unit: GanttHeaderUnit) => string | number,\n headerTipRender?: (date: dayjs.Dayjs, unit: GanttHeaderUnit) => string,\n defaultCol?: DefaultColDef,\n rowHeight?: number,\n headerHeight?: number, // table and gantt view header height\n rowBuffer?: number, // The number of rows rendered outside the viewable area the gantt renders\n rowSelection?: 'single' | 'multiple' | 'none',\n defaultTableViewWidth?: number,\n maxTableViewWidth?: number,\n styleOption?: GanttStyleOption\n timePointComp?: any,\n defaultPerHourSpacing?: number,\n defaultTimeScale?: TimeScale,\n locale?: string,\n defaultShowFirstLevel?: boolean,\n timeLineRender?: any,\n timeLineRenderParams?: Record<string, any>,\n}\n\nconst props = withDefaults(defineProps<GanttOption>(), {\n defaultTableViewWidth: 350,\n maxTableViewWidth: 1000,\n columns: () => [],\n rows: () => [],\n rowHeight: 25,\n rowBuffer: 5,\n rowSelection: 'multiple',\n headerHeight: 25,\n defaultShowFirstLevel: true\n});\n\nconst emit = defineEmits<{\n (event: 'selectChange', selectedIds: string[]): void,\n (event: 'expandChange', unExpandRowIds: string[]): void,\n (event: 'rowContextMenu', e: MouseEvent, rowId?: string | null): void,\n (event: 'cellDoubleClicked', rowData: RowData | undefined, columnData?: ColDef): void\n (event: 'ganttMouseDown', e: MouseEvent, rowId?: string | null): void,\n (event: 'timePointMoveFinished', timePoint: TimePoint, date: dayjs.Dayjs): void,\n (event: 'perHourSpacingChange', perHourSpacing: number): void,\n (event: 'timePointContextMenu', e: MouseEvent, timePoints: TimePoint[], rowData?: RowData): void,\n (event: 'timeLineStretchChange', rowId: string, timeLineIds: string[], startDate: dayjs.Dayjs | null, endDate: dayjs.Dayjs | null): void,\n (event: 'timeLineMoveChange', rowId: string, timeLineIds: string[], movedTimeData: MovedTimeLineData[]): void,\n (event: 'viewPortChanged', data: RowData[]): void | Promise<void>,\n}>();\nconst ganttViewRef = ref<InstanceType<typeof GanttView>>();\nconst tableViewRef = ref<InstanceType<typeof TableView>>();\nconst vGanttRef = ref<HTMLDivElement>();\nconst rowsRef = toRef(props, 'rows');\nconst rowHeightRef = toRef(props, 'rowHeight');\nconst showFirstLevel = toRef(props, 'defaultShowFirstLevel');\nconst rowSelectionRef = toRef(props, 'rowSelection');\nconst showSecondLevel = ref(true);\nconst rowClass = 'vg-row';\nprovide(\n 'showSecondLevel',\n showSecondLevel\n);\n\nprovide(\n 'showFirstLevel',\n showFirstLevel\n);\n\nconst triggerTableViewScroll = (options: ScrollToOptions, onWheel?: boolean) => {\n tableViewRef.value?.scrollTo(options, onWheel);\n};\n\nconst triggerGanttViewScroll = (options: ScrollToOptions) => {\n ganttViewRef.value?.scrollTo(options);\n};\n\nconst emitSelectChange = (ids: string[]) => {\n emit('selectChange', ids);\n};\n\nconst emitExpandChange = (ids: string[]) => {\n emit('expandChange', ids);\n};\n\nconst freshTimeLines = (rowIds: string[]) => {\n const rowNodes: GanttRowNode[] = [];\n rowIds.forEach(id => {\n const currentRowNode = rowNodeMap.value.get(id);\n if (currentRowNode) {\n rowNodes.push(currentRowNode);\n }\n });\n ganttViewRef.value && ganttViewRef.value.freshTimeLines(rowNodes);\n};\n\nconst refreshCells = (ids: string[], force = false) => {\n tableViewRef.value?.refreshCells(ids, force);\n};\n\nconst onCellDoubleClicked = (data: RowData | undefined, columnData?: ColDef) => {\n emit('cellDoubleClicked', data, columnData);\n};\n\nconst emitGanttMouseDown = (event: MouseEvent, rowId: string | null) => {\n emit('ganttMouseDown', event, rowId);\n};\n\nconst onGanttBodyResize = (target: HTMLDivElement) => {\n tableViewRef.value?.handleEmptyRowChanged(target);\n\n};\n\nconst onContextmenu = (event: MouseEvent) => {\n const { attributeValue: rowId } = getTargetElementInfo(event.target as HTMLElement | null, rowClass, 'data-row-id');\n emit('rowContextMenu', event, rowId);\n};\n\nconst timePointMoveFinished = (timePoint: TimePoint, date: dayjs.Dayjs) => {\n emit('timePointMoveFinished', timePoint, date);\n};\n\nprovide(\n 'timePointMoveFinished',\n timePointMoveFinished\n);\n\nconst perHourSpacingChange = (perHourSpacing: number) => {\n emit('perHourSpacingChange', perHourSpacing);\n};\n\nconst timePointContextMenu = (e: MouseEvent, timePoints: TimePoint[], rowNode?: GanttRowNode) => {\n if (rowNode) {\n setSelect(rowNode.id);\n }\n emit('timePointContextMenu', e, timePoints, rowNode?.data);\n};\n\nprovide(\n 'timePointContextMenu',\n timePointContextMenu\n);\n\nconst timeLineStretchChange = (rowId: string, timeLineIds: string[], startDate: dayjs.Dayjs | null, endDate: dayjs.Dayjs | null) => {\n emit('timeLineStretchChange', rowId, timeLineIds, startDate, endDate);\n};\n\nprovide(\n 'timeLineStretchChange',\n timeLineStretchChange\n);\n\nconst timeLineMoveChange = (rowId: string, timeLineIds: string[], movedTimeData: MovedTimeLineData[]) => {\n emit('timeLineMoveChange', rowId, timeLineIds, movedTimeData);\n};\n\nprovide(\n 'timeLineMoveChange',\n timeLineMoveChange\n);\n\n/**\n * when visual area Changed notice user\n * @param data\n */\nconst onViewPortChanged = (data: RowData[]) => {\n emit('viewPortChanged', data);\n};\n\nconst setSelect = (id: string) => {\n handleSetSelect(id);\n};\n\nconst setExpand = (id: string, expand: boolean) => {\n handleSetExpand(id, expand);\n};\n\nconst {\n rowNodeMap,\n rowNodeIds,\n visibleRowIds,\n rowDataList,\n firstLevelRowNode,\n getRowNode,\n getRowNodeChildren,\n getRowDataList,\n freshRowNodes,\n getDisplayRows\n} = useGanttRowNode({\n ganttViewRef,\n tableViewRef,\n rows: rowsRef,\n getRowId: props.getRowId,\n setExpand,\n setSelect,\n refreshCells,\n onViewPortChanged\n});\n\nconst {\n handleSetSelect,\n selectRows,\n getTargetElementInfo\n} = useGanttSelect({\n vGanttRef,\n visibleRowIds,\n rowHeight: rowHeightRef,\n rowSelection: rowSelectionRef,\n rowClass,\n emitGanttMouseDown,\n emitSelectChange\n});\n\nconst {\n handleSetExpand,\n expandAll\n} = useGanttExpand({\n tableViewRef,\n rowNodeMap,\n visibleRowIds,\n rowNodeIds,\n refreshCells,\n emitExpandChange\n});\n\ndefineExpose({\n getRowNode,\n getRowNodeChildren,\n getRowDataList,\n freshRowNodes,\n refreshCells,\n getDisplayRows,\n expandAll,\n freshTimeLines,\n selectRows,\n});\n\ndefineOptions({\n name: 'VueGantt3',\n});\n\n</script>\n<style lang=\"scss\">\n.vue-gantt-3 {\n width: 100%;\n height: 100%;\n display: flex;\n overflow: hidden;\n box-sizing: border-box;\n border: 1px solid #e9e9e9;\n background-color: #fff;\n *, :before, :after {\n box-sizing: border-box;\n }\n img {\n border: 0;\n vertical-align: middle;\n -webkit-user-drag: none;\n user-select: none;\n }\n .c-expandable-box {\n ._drag-line {\n right: -4px !important;\n }\n margin-right: 4px;\n }\n .vg-table-view {\n border-right: 1px solid #e9e9e9;\n }\n .vg-gantt-view {\n flex: 1;\n border-left: 1px solid #e9e9e9;\n }\n}\n</style>"],"names":[],"mappings":"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"}