Skip to content

Commit

Permalink
feat: ✨add gantt header logic
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyjone committed Apr 16, 2023
1 parent be8e167 commit c926e9d
Show file tree
Hide file tree
Showing 11 changed files with 199 additions and 210 deletions.
9 changes: 7 additions & 2 deletions src/components/common/GanttBody.vue
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
<template>
<div class="xg-gantt-body" :style="{ height: bodyHeight }">
<div
class="xg-gantt-body"
:style="{ height: bodyHeight, width: `${ganttWidth}px` }"
>
<div v-for="d in $data.flatData" :key="d.uuid" class="xg-gantt-row">
<component :is="$slotsBox.slider" :data="d" />
</div>
Expand All @@ -8,18 +11,20 @@

<script lang="ts" setup>
import useData from '@/composables/useData';
import useGanttWidth from '@/composables/useGanttWidth';
import useSlotsBox from '@/composables/useSlotsBox';
import useStyle from '@/composables/useStyle';
const { $slotsBox } = useSlotsBox();
const { $data } = useData();
const { bodyHeight } = useStyle();
const { ganttWidth } = useGanttWidth();
</script>

<style lang="scss" scoped>
.xg-gantt-body {
width: calc(100 * 30px);
background-color: darksalmon;
.xg-gantt-row {
Expand Down
2 changes: 1 addition & 1 deletion src/components/common/GanttHeader.vue
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@
:colspan="c.colSpan"
:rowspan="c.rowSpan"
>
{{ c.date }}
{{ c.label }}
</th>
</tr>
</thead>
Expand Down
12 changes: 12 additions & 0 deletions src/composables/useGanttWidth.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { useStore } from '@/store';
import { computed } from 'vue';

export default () => {
const store = useStore();

const ganttWidth = computed(() => {
return store.ganttHeader.headers[1].length * 30;
});

return { ganttWidth };
};
17 changes: 15 additions & 2 deletions src/constants/vars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,21 @@ export const Variables = {
},

time: {
millisecondOfDay: 86400000,
millisecondOfWeek: 604800000
millisecondOf: {
millisecond: 1,
second: 1000,
minute: 60000,
hour: 3600000,
day: 86400000,
week: 604800000
},
aggregation: {
week: 'year',
day: 'month',
hour: 'day',
minute: 'hour',
second: 'minute'
}
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/models/data/all.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { type XDate } from '@/utils/date';
import { isArray } from 'lodash';
import { type XDate } from '../param/date';
import RowItem from './row';

export default class AllData {
Expand Down
2 changes: 1 addition & 1 deletion src/models/data/row.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import { Variables } from '@/constants/vars';
import { type HeaderDateUnit } from '@/typings/ParamOptions';
import { uuid } from '@/utils/common';
import { XDate } from '@/utils/date';
import { cloneDeep, isEqual } from 'lodash';
import { XDate } from '../param/date';

export default class RowItem {
/**
Expand Down
110 changes: 110 additions & 0 deletions src/models/param/date.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
import { day } from '@/utils/date';

export enum DateEnum {
'year',
'month',
'day',
'hour',
'minute',
'second',
'millisecond'
}

/**
* 内部使用的日期对象,所有日期都是用该对象包装
*/
export class XDate {
date: Date;

constructor(date?: Date | number | string) {
this.date = day(date).toDate();
}

/**
* 设置一个新日期
*/
setDate(date: Date) {
this.date = day(date).toDate();
}

/**
* 获取日期的周数文本
*/
toWeek() {
return `第 ${day(this.date).week()} 周`;
}

/**
* 获取日期的月份文本
*/
toMonth() {
return `${day(this.date).month() + 1} 月`;
}

/**
* 获取日期在当月的具体日期的文本
*/
toDate() {
return day(this.date).date().toString();
}

/**
* 获取两个时间的间隔时间戳
*/
intervalTo(date: XDate) {
return this.date.getTime() - date.date.getTime();
}

/**
* 比较大小,返回字符,l 左小,r 右小,e 相等
*/
compareTo(date: XDate) {
const l = this.date.getTime();
const r = date.date.getTime();
if (l < r) return 'l';
if (l > r) return 'r';
return 'e';
}

/**
* 比较日期大小。
* @param date 要比较的日期
* @param precision 精度,可以通过不同单位来调整判断精度
* @returns 返回字符,l 左小,r 右小,e 相等或比较类似的字符串或等等。
*/
isSame(date: XDate, precision: DateUnit) {
if (precision === 'week') {
return day(this.date).week() === day(date.date).week();
}

return (
this.date.toISOString().split(/T|-|:|\./)[DateEnum[precision]] ===
date.date.toISOString().split(/T|-|:|\./)[DateEnum[precision]]
);
}

/**
* 获取一个位移后的日期对象。该对象不会影响原始对象。
*/
getOffset(offset: number) {
return new XDate(day(this.date.getTime() + offset).toDate());
}

/**
* 通过不同单位获取当前时间的不同精度值
*/
getBy(unit: DateUnit) {
if (unit === 'week') return day(this.date).week();

return parseInt(
this.date.toLocaleString().split(/\s|\/|:/)[DateEnum[unit]]
);
}

/**
* 返回一个可格式化的日期字符串
*/
toString(format: string = 'YYYY-MM-DD') {
return day(this.date).format(format);
}
}
77 changes: 48 additions & 29 deletions src/models/param/header.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { type HeaderDateUnit } from '@/typings/ParamOptions';
import { type XDate } from '@/utils/date';
import { XDate } from './date';
import { isArray } from 'lodash';
import { type VNode } from 'vue';
import Variables from '@/constants/vars';

class Column {
children?: Column[];
Expand Down Expand Up @@ -42,12 +42,14 @@ class TableColumn extends Column {

class GanttColumn extends Column {
declare children?: GanttColumn[];
date: string;
date: XDate;
label: string;

constructor() {
constructor(date: XDate, unit: DateUnit) {
super();

this.date = '';
this.date = date;
this.label = this.date.getBy(unit).toString();
}
}

Expand Down Expand Up @@ -169,6 +171,11 @@ class GanttHeader extends Header {
*/
headers: GanttColumn[][] = [];

/**
* 整体的日期列表
*/
dates: XDate[] = [];

start?: XDate;
end?: XDate;
unit: HeaderDateUnit = 'day';
Expand All @@ -185,31 +192,43 @@ class GanttHeader extends Header {
}

generate() {
// TODO:根据日期和单位生成一个树形日期结构

const columns: GanttColumn[] = [
{
date: '2020-1',
rowSpan: 1,
colSpan: 1,
level: 1,
children: [
{ date: '1', rowSpan: 1, colSpan: 1, level: 1 },
{ date: '2', rowSpan: 1, colSpan: 1, level: 1 },
{ date: '3', rowSpan: 1, colSpan: 1, level: 1 }
]
},
{
date: '2020-2',
rowSpan: 1,
colSpan: 1,
level: 1,
children: [
{ date: '1', rowSpan: 1, colSpan: 1, level: 1 },
{ date: '2', rowSpan: 1, colSpan: 1, level: 1 }
]
// 通过 start 和 end 以及 unit 来生成 columns
const columns: GanttColumn[] = [];

const start = this.start!.date.getTime();
const end = this.end!.date.getTime();

// TODO 这里可以优化一下,直接一次循环就可以组成 headers。因为是固定格式
for (
let i = start;
i <= end;
i += Variables.time.millisecondOf[this.unit]
) {
this.dates.push(new XDate(i));
}

let last: number;
let i = -1;
this.dates.forEach(date => {
const cur = date.getBy(Variables.time.aggregation[this.unit] as DateUnit);

if (cur !== last) {
last = cur;
columns.push(
new GanttColumn(
date,
Variables.time.aggregation[this.unit] as DateUnit
)
);
i++;
} else {
if (!columns[i].children) {
columns[i].children = [];
}

columns[i].children?.push(new GanttColumn(date, this.unit));
}
];
});

this.headers = this.convertToRows(columns, this.getAllColumns(columns));
}
Expand Down
72 changes: 0 additions & 72 deletions src/typings/ParamOptions.d.ts

This file was deleted.

3 changes: 3 additions & 0 deletions src/typings/date.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
declare type HeaderDateUnit = 'week' | 'day' | 'hour' | 'minute' | 'second';

declare type DateUnit = 'year' | 'month' | HeaderDateUnit | 'millisecond';
Loading

0 comments on commit c926e9d

Please sign in to comment.