vue-gantt-3
Version:
A gantt component for Vue 3
302 lines (301 loc) • 11.9 kB
JavaScript
"use strict";
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
const vue = require("vue");
const dayjs = require("dayjs");
const common = require("../../../../utils/common.js");
const useTimeLine = ({
rowHeight,
rowBuffer,
perHourSpacing,
scrollViewScrollTop,
scrollViewScrollLeft,
rowNodeMap,
currentVisibleRowIds,
startInfo,
movingTimeLineRowId,
movingTimeLine,
createTimePointNodes
}) => {
const wrapRef = vue.inject("wrapRef");
const visibleRows = vue.shallowRef([]);
const visibleTimeLineMap = vue.shallowRef(/* @__PURE__ */ new Map());
const bufferWidth = 200;
const wrapWidth = vue.ref(0);
const wrapHeight = vue.ref(0);
const freshTimeLineView = () => {
var _a, _b;
wrapWidth.value = ((_a = wrapRef.value) == null ? void 0 : _a.offsetWidth) || 0;
wrapHeight.value = ((_b = wrapRef.value) == null ? void 0 : _b.offsetHeight) || 0;
freshVisibleRows();
freshVisibleTimeLines();
};
const freshTimeLineViewAfterScrollTop = () => {
freshVisibleRows();
freshVisibleTimeLines(false);
};
const freshVisibleRows = () => {
if (!wrapRef.value) return;
const bufferHeight = rowHeight.value * rowBuffer;
const startNumInView = Math.floor((scrollViewScrollTop.value - bufferHeight) / rowHeight.value);
const endNumInView = Math.ceil((scrollViewScrollTop.value + wrapHeight.value + bufferHeight) / rowHeight.value);
const newVisibleRows = [];
const start = Math.max(0, startNumInView);
const end = Math.min(currentVisibleRowIds.value.length - 1, endNumInView);
for (let i = start; i <= end; i++) {
const currentRowId = currentVisibleRowIds.value[i];
const currentRowNode = rowNodeMap.value.get(currentRowId);
if (currentRowNode) {
newVisibleRows.push({
id: currentRowId,
rowNode: currentRowNode,
translateY: i * rowHeight.value
});
const timeLineNodes = sortTimeLinesInRowNode(currentRowNode);
if (timeLineNodes) {
const timeLineNodesAfterCombine = mergeOverlapTimeLine(timeLineNodes);
currentRowNode.timeLineNodes = timeLineNodesAfterCombine;
}
}
}
visibleRows.value = common.arrangementArr(newVisibleRows, visibleRows.value);
};
const sortTimeLinesInRowNode = (rowNode) => {
if (!rowNode.timeLineNodes && rowNode.data.timeLines) {
const timeLineNodes = [];
if (rowNode.hasChildren) {
const timeLineNode = createTimeLineNodeFromRowNode(rowNode);
timeLineNode && timeLineNodes.push(timeLineNode);
} else {
for (let timeLine of rowNode.data.timeLines) {
const timeLineNode = createTimeLineNode(timeLine);
timeLineNodes.push(timeLineNode);
}
}
sortTimeLineNodes(timeLineNodes);
return timeLineNodes;
}
};
const createTimeLineNodeFromRowNode = (rowNode) => {
const startDate = rowNode.startDate;
const endDate = rowNode.endDate;
const styleOption = { backgroundColor: "#000" };
if (startDate && endDate) {
const isSameDate = startDate.isSame(endDate);
const baseNode = {
id: rowNode.id,
startDate,
endDate,
isSameDate,
hasChildren: rowNode.hasChildren,
styleOption
};
return baseNode;
}
};
const sortTimeLineNodes = (timeLineNodes) => {
timeLineNodes.sort((timeLine1, timeLine2) => {
if (timeLine1.startDate.isSame(timeLine2.startDate)) return 0;
if (timeLine1.startDate.isBefore(timeLine2.startDate)) {
return -1;
} else {
return 1;
}
});
};
const mergeOverlapTimeLine = (timeLineNodes) => {
const newTimeLineNodes = [];
for (let timeLineNode of timeLineNodes) {
const lastTimeLineNode = newTimeLineNodes[newTimeLineNodes.length - 1];
if (lastTimeLineNode && !timeLineNode.startDate.isAfter(lastTimeLineNode.endDate)) {
lastTimeLineNode.isMerge = true;
const maxEndDate = dayjs.max([lastTimeLineNode.endDate, timeLineNode.endDate]);
maxEndDate && (lastTimeLineNode.endDate = maxEndDate);
if (!lastTimeLineNode.mergedTimeLineNodes) {
lastTimeLineNode.mergedTimeLineNodes = [lastTimeLineNode];
}
if (timeLineNode.isMerge) {
timeLineNode.isMerge = false;
lastTimeLineNode.mergedTimeLineNodes = lastTimeLineNode.mergedTimeLineNodes.concat(timeLineNode.mergedTimeLineNodes);
timeLineNode.mergedTimeLineNodes = void 0;
} else {
lastTimeLineNode.mergedTimeLineNodes.push(timeLineNode);
}
} else {
newTimeLineNodes.push(timeLineNode);
}
}
return newTimeLineNodes;
};
const createTimeLineNode = (timeLine) => {
const startDate = dayjs(timeLine.startDate);
const endDate = dayjs(timeLine.endDate);
const isSameDate = startDate.isSame(endDate);
const styleOption = { ...timeLine.styleOption };
if (isSameDate) {
styleOption.backgroundColor = "#000";
}
const timePointNodes = createTimePointNodes(timeLine);
const baseNode = {
id: timeLine.id,
timePointNodes,
data: timeLine,
startDate,
endDate,
isSameDate,
styleOption,
icon: timeLine.icon,
label: timeLine.label,
disableStretch: timeLine.disableStretch,
disableMove: timeLine.disableMove
};
return baseNode;
};
const freshVisibleTimeLines = (freshAll = true) => {
var _a;
if (!wrapRef.value) return;
const { startDate } = startInfo.value;
const startLeftInView = scrollViewScrollLeft.value - bufferWidth;
const endLeftInView = scrollViewScrollLeft.value + wrapWidth.value + bufferWidth;
const startDateInView = startDate.add(Math.max(0, startLeftInView) / perHourSpacing.value, "hour");
const endDateInView = startDate.add(endLeftInView / perHourSpacing.value, "hour");
const newVisibleTimeLineMap = /* @__PURE__ */ new Map();
let needFreshRows = [];
if (freshAll) {
needFreshRows = visibleRows.value;
} else {
needFreshRows = visibleRows.value.filter((row) => {
const oldTimeLineCache = visibleTimeLineMap.value.get(row.id);
if (oldTimeLineCache) {
newVisibleTimeLineMap.set(row.id, oldTimeLineCache);
}
return !oldTimeLineCache;
});
}
for (let visibleRow of needFreshRows) {
const rowId = visibleRow.id;
const timeLineNodes = visibleRow.rowNode.timeLineNodes;
if (timeLineNodes) {
const visibleTimeLines = [];
const startIndex = getTimeLineIndexInView(timeLineNodes, startDateInView, "min");
const endIndex = getTimeLineIndexInView(timeLineNodes, endDateInView, "max");
const hasMovingTimeLine = movingTimeLineRowId.value === rowId;
for (let i = startIndex; i < endIndex; i++) {
const currentTimeNode = timeLineNodes[i];
if (hasMovingTimeLine && currentTimeNode.id === ((_a = movingTimeLine.value) == null ? void 0 : _a.id)) continue;
const currentStartDate = currentTimeNode.startDate;
const currentEndDate = currentTimeNode.endDate;
const translateX = currentStartDate.diff(startDate, "hour", true) * perHourSpacing.value;
const width = currentTimeNode.isSameDate ? 0 : currentEndDate.diff(currentStartDate, "hour", true) * perHourSpacing.value;
let type = "normal";
if (currentTimeNode.hasChildren) {
type = "parentTimeLineNode";
} else if (currentTimeNode.isSameDate) {
type = "sameDateTimeLineNode";
}
const originalTimePoints = currentTimeNode.timePointNodes || [];
const timePointNodes = [];
for (let timePointNode of originalTimePoints) {
if (timePointNode.date.isBetween(currentStartDate, currentEndDate, void 0, "[]")) {
const timePointNodeTranslateX = timePointNode.date.diff(currentStartDate, "hour", true) * perHourSpacing.value;
timePointNode.translateX = timePointNodeTranslateX;
timePointNodes.push(timePointNode);
}
}
visibleTimeLines.push({
id: currentTimeNode.id,
startDate: currentTimeNode.startDate,
endDate: currentTimeNode.endDate,
timeLineNode: currentTimeNode,
width,
translateX,
styleOption: currentTimeNode.styleOption,
type,
timePointNodes,
icon: currentTimeNode.icon,
label: currentTimeNode.label,
disableStretch: currentTimeNode.disableStretch,
disableMove: currentTimeNode.disableMove
});
}
if (hasMovingTimeLine) {
visibleTimeLines.push(movingTimeLine.value);
}
newVisibleTimeLineMap.set(rowId, visibleTimeLines);
}
}
visibleTimeLineMap.value = newVisibleTimeLineMap;
};
const getTimeLineIndexInView = (timeLineNodes, targetDate, type) => {
let minIndex = 0;
let maxIndex = timeLineNodes.length - 1;
while (maxIndex >= minIndex) {
const midIndex = Math.floor((minIndex + maxIndex) / 2);
const startDate = timeLineNodes[midIndex].startDate;
const endDate = timeLineNodes[midIndex].endDate;
const currentDate = type === "min" ? endDate : startDate;
if (currentDate.isBefore(targetDate)) {
minIndex = midIndex + 1;
} else {
maxIndex = midIndex - 1;
}
}
return minIndex;
};
const freshTimeLines = (rowNodes) => {
if (rowNodes.length === 0) return;
common.treeForEach(rowNodes, (rowNode) => {
const currentRowId = rowNode.id;
const currentRowNode = rowNodeMap.value.get(currentRowId);
currentRowNode && (currentRowNode.timeLineNodes = void 0);
visibleTimeLineMap.value.delete(currentRowId);
});
freshTimeLineViewAfterScrollTop();
};
const updateParentTimeLine = (rowId) => {
var _a, _b;
const parentRowNode = rowNodeMap.value.get(rowId);
const { startDate } = startInfo.value;
if (parentRowNode) {
const parentTimeLineNode = (_a = parentRowNode.timeLineNodes) == null ? void 0 : _a[0];
const parentVisibleTimeLine = (_b = visibleTimeLineMap.value.get(rowId)) == null ? void 0 : _b[0];
if (parentTimeLineNode) {
const childrenRowNodes = parentRowNode.children || [];
const startDateArr = [];
const endDateArr = [];
for (let childRowNode of childrenRowNodes) {
const childTimeLineNodes = childRowNode.timeLineNodes || [];
for (let childTimeLineNode of childTimeLineNodes) {
startDateArr.push(childTimeLineNode.startDate);
endDateArr.push(childTimeLineNode.endDate);
}
const minStartDate = dayjs.min(startDateArr);
const maxEndDate = dayjs.max(endDateArr);
if (minStartDate && maxEndDate) {
parentTimeLineNode.startDate = minStartDate;
parentTimeLineNode.endDate = maxEndDate;
if (parentVisibleTimeLine) {
const translateX = parentTimeLineNode.startDate.diff(startDate, "hour", true) * perHourSpacing.value;
const width = parentTimeLineNode.endDate.diff(parentTimeLineNode.startDate, "hour", true) * perHourSpacing.value;
parentVisibleTimeLine.translateX = translateX;
parentVisibleTimeLine.width = width;
}
}
}
parentRowNode.parentId && updateParentTimeLine(parentRowNode.parentId);
}
}
};
return {
freshTimeLineView,
freshTimeLineViewAfterScrollTop,
freshTimeLines,
freshVisibleTimeLines,
sortTimeLineNodes,
mergeOverlapTimeLine,
visibleTimeLineMap,
visibleRows,
updateParentTimeLine
};
};
exports.useTimeLine = useTimeLine;
//# sourceMappingURL=useTimeLine.js.map