Skip to content

Commit

Permalink
feat: ✨add jump to date function
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyjone committed May 16, 2023
1 parent cc9969b commit 44f0f9c
Show file tree
Hide file tree
Showing 6 changed files with 127 additions and 25 deletions.
26 changes: 20 additions & 6 deletions demo/demo.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
<template>
<div style="top: 20vh; width: 100%; height: 500px; padding-left: 5vw">
<x-gantt
ref="ganttRef"
data-id="index"
:data="ganttData"
:links="ganttLinks"
Expand All @@ -17,6 +18,7 @@
@move-slider="onMoveSlider"
@add-link="onAddLink"
@click-link="onClickLink"
@no-date-error="onNoDateError"
>
<x-gantt-column label="group1">
<x-gantt-column
Expand Down Expand Up @@ -99,6 +101,7 @@
</button>
<button @click="onChangeBorderColor">border颜色</button>
<button @click="changeUnit">切换单位</button>
<button @click="jumpToDate">跳转到</button>
</div>
</template>

Expand All @@ -117,22 +120,22 @@ ganttData[0].children = [
{
index: ++id,
name: 'sub-t' + id,
startDate: new Date(2023, 4, 1),
endDate: new Date(2023, 4, 5),
startDate: new Date(2023, 3, 1),
endDate: new Date(2023, 3, 5),
o: { t1: 'a', t2: 'b' }
},
{
index: ++id,
name: 'sub-t' + id,
startDate: new Date(2023, 4, 1),
endDate: new Date(2023, 4, 5),
startDate: new Date(2023, 3, 1),
endDate: new Date(2023, 3, 5),
o: { t1: 'a', t2: 'b' },
children: [
{
index: ++id,
name: 'sub-sub-t' + id,
startDate: new Date(2023, 4, 1),
endDate: new Date(2023, 4, 5),
startDate: new Date(2023, 3, 1),
endDate: new Date(2023, 3, 5),
o: { t1: 'a', t2: 'b' }
}
]
Expand Down Expand Up @@ -228,6 +231,17 @@ const onClickLink = (data: any) => {
function onMove(data: any) {
return true;
}
const onNoDateError = () => {
console.log('no date error');
};
const ganttRef = ref(null) as any;
function jumpToDate() {
console.log('jumpToDate', ganttRef.value);
ganttRef.value?.jumpToDate();
}
</script>

<style scoped></style>
17 changes: 5 additions & 12 deletions src/components/root/RootWrap.vue
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,8 @@
</template>

<script lang="ts">
import { defineComponent, useSlots } from 'vue';
import { defineComponent, ref, useSlots } from 'vue';
import { initStore } from '@/store';
import useRoot from '@/composables/useRoot';
import Root from './index.vue';
import useEvent from '@/composables/useEvent';
import { MoveSliderData } from '@/typings/data';
Expand Down Expand Up @@ -38,24 +37,18 @@ initStore();
const { setRootEmit } = useEvent();
setRootEmit(emit);
const { rootRef } = useRoot();
const rootWrapRef = ref(null) as any;
const setSelected = (args: any) => {
(rootRef.value as any)?.setSelected(args);
(rootWrapRef.value as any)?.setSelected(args);
};
const jumpToDate = (args: any) => {
(rootRef.value as any)?.jumpToDate(args);
};
const setHeaderUnit = (args: any) => {
(rootRef.value as any)?.setHeaderUnit(args);
(rootWrapRef.value as any)?.jumpToDate(args);
};
// ***** 对外方法 ***** //
defineExpose({
setSelected,
jumpToDate,
setHeaderUnit
jumpToDate
});
</script>

Expand Down
3 changes: 2 additions & 1 deletion src/components/root/index.vue
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,8 @@ onResizeTableColumn(midLineRef, {
console.log('.....root', getCurrentInstance());
// #region 暴露方法
defineExpose(useExport());
const exports = useExport(ganttRef);
defineExpose(exports);
// #endregion
</script>

Expand Down
91 changes: 88 additions & 3 deletions src/composables/useExport.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,92 @@
export default () => {
import { XDate } from '@/models/param/date';
import { isDate, isUndefined } from 'lodash';
import { type Ref, type DefineComponent } from 'vue';
import useEvent from './useEvent';
import useGanttHeader from './useGanttHeader';
import useGanttWidth from './useGanttWidth';
import useToday from './useToday';

export default (ganttRef: Ref<DefineComponent | null>) => {
const { isInArea } = useToday();
const { EmitNoDateError } = useEvent();
const { ganttHeader } = useGanttHeader();
const { ganttColumnWidth, currentMillisecond } = useGanttWidth();

/**
* 跳转到某个日期
*/
function handleJumpTo(_date: Date | undefined) {
if (!ganttRef.value) return;

let date: XDate;

// 未定义日期,默认跳转到今天
if (isUndefined(_date) || !isDate(_date)) {
date = new XDate();
} else {
date = new XDate(_date);
}

if (!isInArea(date)) {
EmitNoDateError();
return;
}

date.startOf(ganttHeader.unit);
const width =
(date.intervalTo(ganttHeader.start) / currentMillisecond.value) *
ganttColumnWidth.value;

let left = 0;
let right = 0;

if (ganttRef.value.$el.scrollLeft < width) {
// 日期在右侧
right = width - ganttRef.value.$el.clientWidth / 3;
} else {
// 日期在左侧
left = Math.abs(ganttRef.value.$el.clientWidth / 6 - width);
}

// 滚动动画,ease-in模式
if (left && right) return;

const duration = 1000;
const distance = left || right;
let oldTimestamp: number | null = null;
let scrollX = 0;
let oldLeft: number | undefined; // 初始不定义,保证第一次不会匹配

function step(newTimestamp: number) {
if (oldTimestamp !== null && ganttRef.value) {
// if duration is 0 scrollX will be -Infinity
if (
ganttRef.value.$el.scrollLeft < left ||
(right > 0 && ganttRef.value.$el.scrollLeft >= right) ||
oldLeft === ganttRef.value.$el.scrollLeft
)
return;

const x = (distance * (newTimestamp - oldTimestamp)) / duration;
if (left) {
scrollX -= x;
} else if (right) {
scrollX += x;
} else {
return;
}
oldLeft = ganttRef.value.$el.scrollLeft;
// eslint-disable-next-line @typescript-eslint/restrict-plus-operands
ganttRef.value.$el.scrollLeft += scrollX;
}
oldTimestamp = newTimestamp;
window.requestAnimationFrame(step);
}
window.requestAnimationFrame(step);
}

return {
setSelected: () => {},
jumpToDate: () => {},
setHeaderUnit: () => {}
jumpToDate: handleJumpTo
};
};
7 changes: 4 additions & 3 deletions src/composables/useToday.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ export default () => {
function isInArea(date: XDate) {
if (ganttHeader.dates.length === 0) return false;

const sd = ganttHeader.dates[0];
const ed = ganttHeader.dates[ganttHeader.dates.length - 1];
const sd = ganttHeader.start;
const ed = ganttHeader.end;

return sd?.compareTo(date) === 'l' && ed?.compareTo(date) === 'r';
}
Expand All @@ -40,6 +40,7 @@ export default () => {

return {
todayLeft,
showToday
showToday,
isInArea
};
};
8 changes: 8 additions & 0 deletions src/models/param/header.ts
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,14 @@ class GanttHeader extends Header {
*/
dates: XDate[] = [];

/**
* 甘特的起始时间(数据起始时间请使用 data.start)
*/
start?: XDate;

/**
* 甘特的结束时间(数据结束时间请使用 data.end)
*/
end?: XDate;
unit: HeaderDateUnit = 'day';
minLength: number = 0;
Expand Down Expand Up @@ -268,6 +275,7 @@ class GanttHeader extends Header {
});

this.headers = this.convertToRows(columns, this.getAllColumns(columns));
this.end = this.dates[this.dates.length - 1];
}

/**
Expand Down

0 comments on commit 44f0f9c

Please sign in to comment.