Skip to content

Commit

Permalink
feat: ✨generate gantt header logic
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyjone committed Apr 15, 2023
1 parent b753fd8 commit 145c65a
Show file tree
Hide file tree
Showing 5 changed files with 165 additions and 72 deletions.
31 changes: 9 additions & 22 deletions src/components/common/GanttHeader.vue
Original file line number Diff line number Diff line change
@@ -1,33 +1,21 @@
<template>
<table class="xg-gantt-header" cellpadding="0" cellspacing="0" border="0">
<colgroup>
<template v-for="i in 100" :key="i">
<template v-for="i in dateList[1].length" :key="i">
<col width="30px" />
</template>
</colgroup>
<thead>
<tr>
<tr v-for="(r, trIndex) in dateList" :key="trIndex">
<th
v-for="i in 10"
v-for="(c, i) in r"
:key="i"
class="xg-gantt-header-cell"
:style="{ ...$styleBox.getBorderColor() }"
colspan="10"
rowspan="1"
:colspan="c.colSpan"
:rowspan="c.rowSpan"
>
{{ i }}
</th>
</tr>
<tr>
<th
v-for="i in 100"
:key="i"
class="xg-gantt-header-cell"
:style="{ ...$styleBox.getBorderColor() }"
colspan="1"
rowspan="1"
>
{{ i }}
{{ c.date }}
</th>
</tr>
</thead>
Expand All @@ -37,13 +25,12 @@
<script lang="ts" setup>
import useData from '@/composables/useData';
import useStyle from '@/composables/useStyle';
import { dateList } from '@/utils/date';
const { $styleBox } = useStyle();
const { $data } = useData();
const l = dateList($data.start, $data.end, 'day');
console.log('lll', l);
const { getDateList } = useData();
const dateList = getDateList();
console.log('getDateList', dateList);
</script>

<style lang="scss" scoped>
Expand Down
7 changes: 6 additions & 1 deletion src/composables/useData.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,5 +17,10 @@ export default () => {
);
}

return { $data: store.$data, initData };
function getDateList() {
store.ganttHeader.setDate(store.$data.start, store.$data.end);
return store.ganttHeader.headers;
}

return { $data: store.$data, initData, getDateList };
};
184 changes: 138 additions & 46 deletions src/models/param/header.ts
Original file line number Diff line number Diff line change
@@ -1,77 +1,63 @@
import { isArray } from 'lodash';
import { type VNode } from 'vue';

class TableColumn {
node: VNode;
/**
* 非叶子结点只接收 label 参数作为标题
*/
label: string;
children?: TableColumn[];
parent?: TableColumn;
class Column {
children?: Column[];
level: number;
colSpan: number;
rowSpan: number;

/**
*
*/
constructor(node: VNode, parent?: TableColumn) {
this.node = node;
this.label = node.props?.label ?? '';
this.parent = parent;
constructor() {
this.level = 1;
this.colSpan = 1;
this.rowSpan = 1;
}
}

class TableHeader {
columns: TableColumn[] = [];
leafs: TableColumn[] = [];

class TableColumn extends Column {
node: VNode;
/**
* 表头渲染使用
* 非叶子结点只接收 label 参数作为标题
*/
headers: TableColumn[][] = [];
label: string;
declare children?: TableColumn[];
parent?: TableColumn;

/**
* 添加表头
*
*/
setColumn(v: VNode) {
// 如果是 column,需要放进 headers 中。并且需要判断是不是有子项(多级表头使用)
this.columns.push(new TableColumn(v));
constructor(node: VNode, parent?: TableColumn) {
super();

this.node = node;
this.label = node.props?.label ?? '';
this.parent = parent;
}
}

/**
* 添加子表头
*/
setSubColumn(node: VNode, parent: TableColumn): TableColumn {
const newItem = new TableColumn(node, parent);
if (isArray(parent.children)) {
parent.children?.push(newItem);
} else {
parent.children = [newItem];
}
class GanttColumn extends Column {
declare children?: GanttColumn[];
date: string;

return newItem;
}
constructor() {
super();

/**
* 当注入完数据,需要生成所需的内容
*/
generate() {
this.headers = this.convertToRows(this.columns);
this.date = '';
}
}

class Header {
/**
* This function idea from https://github.com/elemefe/element
* 将 columns 内容转换为行的内容,这样才能循环渲染多级表头
*/
private convertToRows(columns: TableColumn[]) {
protected convertToRows<T extends Column>(columns: T[], allColumns: T[]) {
let maxLevel = 1;

const traverse = (column: TableColumn, parent?: TableColumn) => {
const traverse = (column: T, parent?: T) => {
if (parent) {
column.level = parent.level + 1;
if (maxLevel < column.level) {
Expand All @@ -81,7 +67,7 @@ class TableHeader {
if (column.children) {
let colSpan = 0;
column.children.forEach(subColumn => {
traverse(subColumn, column);
traverse(subColumn as T, column);
colSpan += subColumn.colSpan;
});
column.colSpan = colSpan;
Expand All @@ -95,13 +81,11 @@ class TableHeader {
traverse(column);
});

const rows: TableColumn[][] = [];
const rows: T[][] = [];
for (let i = 0; i < maxLevel; i++) {
rows.push([]);
}

const allColumns = this.getAllColumns(columns);

allColumns.forEach(column => {
if (!column.children) {
column.rowSpan = maxLevel - column.level + 1;
Expand All @@ -113,6 +97,48 @@ class TableHeader {

return rows;
}
}

class TableHeader extends Header {
columns: TableColumn[] = [];
leafs: TableColumn[] = [];

/**
* 表头渲染使用
*/
headers: TableColumn[][] = [];

/**
* 添加表头
*/
setColumn(v: VNode) {
// 如果是 column,需要放进 headers 中。并且需要判断是不是有子项(多级表头使用)
this.columns.push(new TableColumn(v));
}

/**
* 添加子表头
*/
setSubColumn(node: VNode, parent: TableColumn): TableColumn {
const newItem = new TableColumn(node, parent);
if (isArray(parent.children)) {
parent.children?.push(newItem);
} else {
parent.children = [newItem];
}

return newItem;
}

/**
* 当注入完数据,需要生成所需的内容
*/
generate() {
this.headers = this.convertToRows(
this.columns,
this.getAllColumns(this.columns)
);
}

/**
* This function idea from https://github.com/elemefe/element
Expand All @@ -135,4 +161,70 @@ class TableHeader {
}
}

export { TableHeader };
class GanttHeader extends Header {
/**
* 表头渲染使用
*/
headers: GanttColumn[][] = [];

start: Date | null = null;
end: Date | null = null;

/**
* 设置日期
*/
setDate(start: Date | null, end: Date | null) {
this.start = start;
this.end = end;

this.generate();
}

generate() {
// TODO:根据日期生成一个树形日期结构
// 结构大体:[{date: 2020-1, children: [{date: 1}, {date: 2}, {date: 3}]}, {date: 2020-2, children: [{date: 1}, {date: 2}]}]
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 }
]
}
];

this.headers = this.convertToRows(columns, this.getAllColumns(columns));
}

/**
* This function idea from https://github.com/elemefe/element
*/
private getAllColumns(columns: GanttColumn[]) {
const result: GanttColumn[] = [];
columns.forEach(column => {
if (column.children) {
result.push(column);
result.push.apply(result, this.getAllColumns(column.children));
} else {
result.push(column);
}
});
return result;
}
}

export { TableHeader, GanttHeader };
3 changes: 2 additions & 1 deletion src/models/param/index.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import SlotsBox from './slotsBox';
import StyleBox from './styles';
import { GanttHeader } from './header';

export { SlotsBox, StyleBox };
export { SlotsBox, StyleBox, GanttHeader };
12 changes: 10 additions & 2 deletions src/store/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import { inject, provide, reactive, type Ref, ref } from 'vue';
import EventBus from '@/utils/bus';
import { AllData } from '@/models/data';
import { SlotsBox, StyleBox } from '@/models/param';
import { GanttHeader, SlotsBox, StyleBox } from '@/models/param';

export const initStore = () => {
const Bus = reactive(new EventBus());
Expand All @@ -26,6 +26,9 @@ export const initStore = () => {

const styleBox = reactive(new StyleBox());
provide('$styleBox', styleBox);

const ganttHeader = reactive(new GanttHeader());
provide('ganttHeader', ganttHeader);
};

export const useStore = () => {
Expand Down Expand Up @@ -53,7 +56,12 @@ export const useStore = () => {
/**
* 样式盒子,所有样式都保存在这里来管理样式
*/
$styleBox: inject('$styleBox') as StyleBox
$styleBox: inject('$styleBox') as StyleBox,

/**
* 甘特图的表头类
*/
ganttHeader: inject('ganttHeader') as GanttHeader
};
};

Expand Down

0 comments on commit 145c65a

Please sign in to comment.