Skip to content

Commit

Permalink
Coding gantt layout functions.
Browse files Browse the repository at this point in the history
  • Loading branch information
gudaoxuri committed Jun 14, 2024
1 parent 0cda067 commit 03bad91
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 34 deletions.
9 changes: 5 additions & 4 deletions src/components/function/Pagination.vue
Original file line number Diff line number Diff line change
Expand Up @@ -101,24 +101,25 @@ async function setSlice(newPage?: number, newFetchNumber?: number) {

<template>
<div style="position: sticky; right: 0; " class="z-[3000]">
<button v-if="getCurrentPage() > 2" class="iw-btn iw-btn-ghost pl-1 pr-1 iw-btn-xs" @click="setCurrentPage(1)">
<button v-if="getCurrentPage() > 2" class="iw-btn iw-btn-ghost px-1 iw-btn-xs" @click="setCurrentPage(1)">
<i :class="iconSvg.FIRST" />
</button>
<button v-if="getCurrentPage() > 1" class="iw-btn iw-btn-ghost pl-1 pr-1 ml-1 iw-btn-xs" @click="setCurrentPage(getCurrentPage() - 1)">
<button v-if="getCurrentPage() > 1" class="iw-btn iw-btn-ghost px-1 ml-1 iw-btn-xs" @click="setCurrentPage(getCurrentPage() - 1)">
<i :class="iconSvg.PREVIOUS" />
</button>
<button
v-for="page in getShowPages()"
:key="page"
:class="`iw-btn iw-btn-ghost pl-3 pr-3 ml-1 iw-btn-xs ${page === getCurrentPage() ? 'iw-btn-active' : ''}`"
:disabled="page === getCurrentPage()"
@click="setCurrentPage(page)"
>
{{ page }}
</button>
<button v-if="getCurrentPage() < getTotalPage()" class="iw-btn iw-btn-ghost pl-1 pr-1 ml-1 iw-btn-xs" @click="setCurrentPage(getCurrentPage() + 1)">
<button v-if="getCurrentPage() < getTotalPage()" class="iw-btn iw-btn-ghost px-1 ml-1 iw-btn-xs" @click="setCurrentPage(getCurrentPage() + 1)">
<i :class="iconSvg.NEXT" />
</button>
<button v-if="getCurrentPage() < getTotalPage() - 1" class="iw-btn iw-btn-ghost pl-1 pr-1 ml-1 iw-btn-xs" @click="setCurrentPage(getTotalPage())">
<button v-if="getCurrentPage() < getTotalPage() - 1" class="iw-btn iw-btn-ghost px-1 ml-1 iw-btn-xs" @click="setCurrentPage(getTotalPage())">
<i :class="iconSvg.LAST" />
</button>
<button class="iw-btn ml-1 mr-1 iw-btn-xs" @click="(e) => { fetchNumberSelectCompRef?.show(e.target as HTMLElement, MenuOffsetKind.MEDIUM_BOTTOM, MenuSizeKind.MINI) }">
Expand Down
52 changes: 36 additions & 16 deletions src/components/layout/gantt/Gantt.vue
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ const props = defineProps<
const { t } = locales.global
const ganttRef: Ref<HTMLElement | null> = ref(null)
const ganttListRef: Ref<HTMLElement | null> = ref(null)
const ganttTimelineRef: Ref<HTMLElement | null> = ref(null)
const ganttWith: Ref<number> = ref(0)
const ganttInfo: Ref<GanttInfo | null> = ref(null)
Expand All @@ -39,21 +41,19 @@ async function generateGanttInfo(data: TableDataResp | TableDataGroupResp[]) {
// Determine the start and end time of the timeline based on the returned data
if (Array.isArray(data)) {
data.forEach((groupData) => {
groupData.records.forEach((d) => {
try {
const { startDate, endDate } = getStartAndEndDay(d.records, props.layout.ganttPlanStartTimeColumnName, props.layout.ganttPlanEndTimeColumnName, props.layout.ganttActualStartTimeColumnName, props.layout.ganttActualEndTimeColumnName)
if (timelineStartDate === null || startDate < timelineStartDate) {
timelineStartDate = startDate
}
if (timelineEndDate === null || endDate > timelineEndDate) {
timelineEndDate = endDate
}
try {
const { startDate, endDate } = getStartAndEndDay(groupData.records, props.layout.ganttPlanStartTimeColumnName, props.layout.ganttPlanEndTimeColumnName, props.layout.ganttActualStartTimeColumnName, props.layout.ganttActualEndTimeColumnName)
if (timelineStartDate === null || startDate < timelineStartDate) {
timelineStartDate = startDate
}
catch (e: any) {
showAlert(e.message, 2, AlertKind.WARNING, getParentWithClass(ganttRef.value, 'iw-tt')!)
hasError = true
if (timelineEndDate === null || endDate > timelineEndDate) {
timelineEndDate = endDate
}
})
}
catch (e: any) {
showAlert(e.message, 2, AlertKind.WARNING, getParentWithClass(ganttRef.value, 'iw-tt')!)
hasError = true
}
})
}
else {
Expand Down Expand Up @@ -95,6 +95,12 @@ onMounted(() => {
return col
})
ganttWith.value = ganttRef.value!.offsetWidth
ganttTimelineRef.value!.addEventListener('scroll', () => {
ganttListRef.value!.scrollTo({
top: ganttTimelineRef.value!.scrollTop,
})
})
})
eb.registerLoadDataAfterEvent(async (data: TableDataResp | TableDataGroupResp[], layoutId: string) => {
Expand All @@ -117,10 +123,11 @@ async function setNewWidth(newWidth: number, _itemId?: string) {
ref="ganttRef"
class="iw-gantt flex h-full"
>
<div class="overflow-auto" :style="`width: ${ganttWith - props.layout.ganttTimelineWidth}px`">
<div ref="ganttListRef" class="overflow-y-hidden overflow-x-auto" :style="`width: ${ganttWith - props.layout.ganttTimelineWidth}px`">
<ListComp :layout="props.layout" :basic="props.basic" />
</div>
<div
ref="ganttTimelineRef"
class="iw-gantt-timeline-container overflow-auto border-l-2 border-l-base-300"
:style="`width: ${props.layout.ganttTimelineWidth}px`"
>
Expand All @@ -144,8 +151,12 @@ async function setNewWidth(newWidth: number, _itemId?: string) {
<template v-else-if="props.layout.data && Array.isArray(props.layout.data)">
<template v-for="groupData in props.layout.data" :key="`${props.layout.id}-${groupData.groupValue}`">
<div
:class="`${props.basic.styles.rowClass} iw-gantt-timeline-row flex bg-base-100 border-b border-b-base-300 border-r border-r-base-300`"
>&nbsp;</div>
:class="`${props.basic.styles.rowClass} iw-gantt-timeline-row flex bg-base-100 border-y border-y-base-300 border-r border-r-base-300 text-sm`"
>
<div class="iw-gantt-timeline-cell">
&nbsp;
</div>
</div>
<GanttTimelineRowComp
:records="groupData.records"
:pk-column-name="props.basic.pkColumnName"
Expand All @@ -155,6 +166,15 @@ async function setNewWidth(newWidth: number, _itemId?: string) {
:style-conf="props.basic.styles"
:gantt-info="ganttInfo"
/>
<div
class="flex justify-end p-2 min-h-0"
>
<div>
<button class="iw-btn ml-1 iw-btn-xs" style="visibility: hidden;">
For placeholder only, highly aligned with paging controls
</button>
</div>
</div>
</template>
</template>
</div>
Expand Down
2 changes: 1 addition & 1 deletion src/components/layout/gantt/GanttTimelineHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function getCateColumTimeline() {

<template>
<div
:class="`${props.styleConf.headerClass} flex items-center flex-col bg-base-200`"
:class="`${props.styleConf.headerClass} flex items-center flex-col sticky top-0 z-[1500] bg-base-200`"
>
<div v-if="ganttInfo.ganttShowKind !== GanttShowKind.YEAR" class="flex items-center">
<div
Expand Down
4 changes: 1 addition & 3 deletions src/components/layout/gantt/GanttTimelineRows.vue
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,7 @@
import type { Dayjs } from 'dayjs'
import dayjs from 'dayjs'
import { nextTick, onMounted, ref, watch } from 'vue'
import type { TableDataGroupResp, TableDataResp } from '../../../props'
import { GanttShowKind, SubDataShowKind } from '../../../props'
import * as eb from '../../eventbus'
import type { TableLayoutConf, TableStyleConf } from '../../conf'
import type { GanttInfo } from './gantt'
Expand Down Expand Up @@ -102,7 +100,7 @@ onMounted(() => {
${timeline.holiday && 'bg-base-200'}
${idx !== 0 && 'border-l border-l-base-300'}`"
>
<div v-if="timeline.today" class="bg-info pl-0.5 h-3/4" />
<div v-if="timeline.today" class="bg-accent pl-0.5 mr-0.5 h-3/4" />
<template v-else>
&nbsp;
</template>
Expand Down
31 changes: 21 additions & 10 deletions src/components/layout/gantt/gantt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,19 +26,19 @@ export interface TimelineInfo {
}

export function getStartAndEndDay(records: { [key: string]: any }[], planStartTimeColumnName?: string, planEndTimeColumnName?: string, actualStartTimeColumnName?: string, actualEndTimeColumnName?: string): { startDate: Date, endDate: Date } {
let timelineStartDate = new Date('9999-12-31')
let timelineEndDate = new Date('1970-01-01')
let timelineStartDate: Date | null = null
let timelineEndDate: Date | null = null
records.forEach((d) => {
if (planStartTimeColumnName && planEndTimeColumnName) {
const startDate = d[planStartTimeColumnName] ? d[planStartTimeColumnName] instanceof Date ? d[planStartTimeColumnName] : new Date(d[planStartTimeColumnName]) : null
const endDate = d[planEndTimeColumnName] ? d[planEndTimeColumnName] instanceof Date ? d[planEndTimeColumnName] : new Date(d[planEndTimeColumnName]) : null
if (startDate && endDate && startDate > endDate) {
throw new Error(t('gantt.error.startDateGreaterThanEndDate', { startDate: dayjs(startDate).format('YYYY-MM-DD HH:mm:ss.SSS'), endDate: dayjs(endDate).format('YYYY-MM-DD HH:mm:ss.SSS') }))
}
else if (startDate && timelineStartDate > startDate) {
else if (startDate && (!timelineStartDate || timelineStartDate > startDate)) {
timelineStartDate = startDate
}
else if (endDate && timelineEndDate < endDate) {
else if (endDate && (!timelineEndDate || timelineEndDate < endDate)) {
timelineEndDate = endDate
}
}
Expand All @@ -48,23 +48,34 @@ export function getStartAndEndDay(records: { [key: string]: any }[], planStartTi
if (startDate && endDate && startDate > endDate) {
throw new Error(t('gantt.error.startDateGreaterThanEndDate', { startDate: dayjs(startDate).format('YYYY-MM-DD HH:mm:ss.SSS'), endDate: dayjs(endDate).format('YYYY-MM-DD HH:mm:ss.SSS') }))
}
else if (startDate && timelineStartDate > startDate) {
else if (startDate && (!timelineStartDate || timelineStartDate > startDate)) {
timelineStartDate = startDate
}
else if (endDate && timelineEndDate < endDate) {
else if (endDate && (!timelineEndDate || timelineEndDate < endDate)) {
timelineEndDate = endDate
}
}
})
if (timelineStartDate > timelineEndDate || timelineStartDate === new Date('9999-12-31') || timelineEndDate === new Date('1970-01-01')) {
if (!timelineStartDate && !timelineEndDate) {
// Use the previous and next 10 days of the current time
timelineStartDate = dayjs().subtract(10, 'day').toDate()
timelineEndDate = dayjs().add(10, 'day').toDate()
}
else {
timelineStartDate = dayjs(timelineStartDate).subtract(10, 'day').toDate()
timelineEndDate = dayjs(timelineEndDate).add(10, 'day').toDate()
else if (timelineStartDate && !timelineEndDate) {
timelineEndDate = dayjs(timelineStartDate).add(1, 'day').toDate()
}
else if (!timelineStartDate && timelineEndDate) {
timelineStartDate = dayjs(timelineEndDate).subtract(1, 'day').toDate()
}
else if (timelineStartDate! > timelineEndDate!) {
// Switch
const temp = timelineStartDate
timelineStartDate = timelineEndDate
timelineEndDate = temp
}

timelineStartDate = dayjs(timelineStartDate).subtract(10, 'day').toDate()
timelineEndDate = dayjs(timelineEndDate).add(10, 'day').toDate()
return { startDate: timelineStartDate, endDate: timelineEndDate }
}

Expand Down

0 comments on commit 03bad91

Please sign in to comment.