From ac1c25259db73ff814ddd8f4662c29a3d3bea7b4 Mon Sep 17 00:00:00 2001 From: cmq Date: Wed, 23 Jun 2021 18:22:31 +0800 Subject: [PATCH] feat: support week view and add test(#INFR-1996) (#113) * fix: remove console.log * fix: fix review code(#INFR-1996) * fix: fix test erro * feat: fix test * fix(view): fix week view cellWidth Co-authored-by: zhangwen <1062680993@qq.com> --- example/src/app/gantt/gantt.component.html | 1 + packages/gantt/src/class/view-type.ts | 3 +- packages/gantt/src/views/factory.ts | 3 + packages/gantt/src/views/test/factory.spec.ts | 6 ++ packages/gantt/src/views/test/week.spec.ts | 45 +++++++++++++ packages/gantt/src/views/view.ts | 3 + packages/gantt/src/views/week.ts | 66 +++++++++++++++++++ 7 files changed, 126 insertions(+), 1 deletion(-) create mode 100644 packages/gantt/src/views/test/week.spec.ts create mode 100644 packages/gantt/src/views/week.ts diff --git a/example/src/app/gantt/gantt.component.html b/example/src/app/gantt/gantt.component.html index 08c3cdb1..b795ecc4 100644 --- a/example/src/app/gantt/gantt.component.html +++ b/example/src/app/gantt/gantt.component.html @@ -3,6 +3,7 @@ 视图: + diff --git a/packages/gantt/src/class/view-type.ts b/packages/gantt/src/class/view-type.ts index e13e25be..7cd69bb7 100644 --- a/packages/gantt/src/class/view-type.ts +++ b/packages/gantt/src/class/view-type.ts @@ -2,5 +2,6 @@ export enum GanttViewType { day = 'day', quarter = 'quarter', month = 'month', - year = 'year' + year = 'year', + week = 'week' } diff --git a/packages/gantt/src/views/factory.ts b/packages/gantt/src/views/factory.ts index 29b9870c..7e2e6f63 100644 --- a/packages/gantt/src/views/factory.ts +++ b/packages/gantt/src/views/factory.ts @@ -4,11 +4,14 @@ import { GanttDate } from '../utils/date'; import { GanttViewType } from '../class/view-type'; import { GanttViewQuarter } from './quarter'; import { GanttViewDay } from './day'; +import { GanttViewWeek } from './week'; export function createViewFactory(type: GanttViewType, start: GanttViewDate, end: GanttViewDate, options?: GanttViewOptions) { switch (type) { case GanttViewType.month: return new GanttViewMonth(start, end, options); + case GanttViewType.week: + return new GanttViewWeek(start, end, options); case GanttViewType.quarter: return new GanttViewQuarter(start, end, options); case GanttViewType.day: diff --git a/packages/gantt/src/views/test/factory.spec.ts b/packages/gantt/src/views/test/factory.spec.ts index 6fefb3be..ee355d04 100644 --- a/packages/gantt/src/views/test/factory.spec.ts +++ b/packages/gantt/src/views/test/factory.spec.ts @@ -4,6 +4,7 @@ import { GanttViewQuarter } from '../quarter'; import { createViewFactory } from '../factory'; import { GanttViewType } from '../../class'; import { date } from './mock'; +import { GanttViewWeek } from '../week'; describe('CreateViewFactory', () => { it(`should be day view`, () => { @@ -11,6 +12,11 @@ describe('CreateViewFactory', () => { expect(dayView).toEqual(jasmine.any(GanttViewDay)); }); + it(`should be week view`, () => { + const weekView = createViewFactory(GanttViewType.week, date.start, date.end); + expect(weekView).toEqual(jasmine.any(GanttViewWeek)); + }); + it(`should be month view`, () => { const monthView = createViewFactory(GanttViewType.month, date.start, date.end); expect(monthView).toEqual(jasmine.any(GanttViewMonth)); diff --git a/packages/gantt/src/views/test/week.spec.ts b/packages/gantt/src/views/test/week.spec.ts new file mode 100644 index 00000000..79f99f58 --- /dev/null +++ b/packages/gantt/src/views/test/week.spec.ts @@ -0,0 +1,45 @@ +import { GanttDate } from '../../utils/date'; +import { GanttViewWeek } from '../week'; +import { date, today } from './mock'; + +describe('GanttViewWeek', () => { + let ganttViewWeek: GanttViewWeek; + + beforeEach(() => { + ganttViewWeek = new GanttViewWeek(date.start, date.end, { + cellWidth: 140, + start: today.startOfYear().startOfWeek({ weekStartsOn: 1 }), + end: today.endOfYear().endOfWeek({ weekStartsOn: 1 }) + }); + }); + + it(`should has correct view start`, () => { + const startOfWeek = ganttViewWeek.startOf(date.start.date).getUnixTime(); + expect(startOfWeek).toEqual(new GanttDate('2019-12-30 00:00:00').getUnixTime()); + }); + + it(`should has correct view end`, () => { + const endOfWeek = ganttViewWeek.endOf(date.end.date).getUnixTime(); + expect(endOfWeek).toEqual(new GanttDate('2021-01-03 23:59:59').getUnixTime()); + }); + + it(`should has correct cell width`, () => { + const weekCellWidth = ganttViewWeek.getDayOccupancyWidth(); + expect(weekCellWidth).toEqual(20); + }); + + it(`should has correct primary width`, () => { + const weekPrimaryWidth = ganttViewWeek.getPrimaryWidth(); + expect(weekPrimaryWidth).toEqual(140); + }); + + it(`should has correct primary date points`, () => { + const weekPoints = ganttViewWeek.getPrimaryDatePoints(); + expect(weekPoints.length).toBe(54); + }); + + it(`should has correct secondary date points`, () => { + const weekPoints = ganttViewWeek.getSecondaryDatePoints(); + expect(weekPoints.length).toBe(54); + }); +}); diff --git a/packages/gantt/src/views/view.ts b/packages/gantt/src/views/view.ts index 0a663141..45312972 100644 --- a/packages/gantt/src/views/view.ts +++ b/packages/gantt/src/views/view.ts @@ -171,6 +171,9 @@ export abstract class GanttView { return matchDate?.start; } else { const day = Math.floor((x % this.getCellWidth()) / dayWidth) + 1; + if (this.getCellWidth() / dayWidth === 7) { + return matchDate?.start.addDays(day); + } return matchDate?.start.setDate(day); } } diff --git a/packages/gantt/src/views/week.ts b/packages/gantt/src/views/week.ts new file mode 100644 index 00000000..2b7971c2 --- /dev/null +++ b/packages/gantt/src/views/week.ts @@ -0,0 +1,66 @@ +import { GanttDatePoint } from '../class/date-point'; +import { eachWeekOfInterval, GanttDate } from '../utils/date'; +import { GanttView, GanttViewDate, GanttViewOptions, primaryDatePointTop, secondaryDatePointTop } from './view'; + +const viewOptions: GanttViewOptions = { + cellWidth: 280, + start: new GanttDate().startOfYear().startOfWeek({ weekStartsOn: 1 }), + end: new GanttDate().endOfYear().endOfWeek({ weekStartsOn: 1 }), + addAmount: 1, + addUnit: 'month' +}; + +export class GanttViewWeek extends GanttView { + constructor(start: GanttViewDate, end: GanttViewDate, options?: GanttViewOptions) { + super(start, end, Object.assign({}, viewOptions, options)); + } + + startOf(date: GanttDate) { + return date.startOfWeek({ weekStartsOn: 1 }); + } + + endOf(date: GanttDate) { + return date.endOfWeek({ weekStartsOn: 1 }); + } + + getPrimaryWidth() { + return this.getCellWidth(); + } + + getDayOccupancyWidth(): number { + return this.cellWidth / 7; + } + + getPrimaryDatePoints(): GanttDatePoint[] { + const weeks = eachWeekOfInterval({ start: this.start.value, end: this.end.addSeconds(1).value }, { weekStartsOn: 1 }); + const points: GanttDatePoint[] = []; + for (let i = 0; i < weeks.length; i++) { + const weekStart = new GanttDate(weeks[i]); + const increaseWeek = weekStart.getDaysInMonth() - weekStart.getDate() >= 3 ? 0 : 1; + const point = new GanttDatePoint( + weekStart, + weekStart.addWeeks(increaseWeek).format('yyyy年'), + this.getCellWidth() / 2 + i * this.getCellWidth(), + primaryDatePointTop + ); + points.push(point); + } + return points; + } + + getSecondaryDatePoints(): GanttDatePoint[] { + const weeks = eachWeekOfInterval({ start: this.start.value, end: this.end.value }); + const points: GanttDatePoint[] = []; + for (let i = 0; i < weeks.length; i++) { + const start = new GanttDate(weeks[i]); + const point = new GanttDatePoint( + start, + `第${start.format('w')}周`, + i * this.getCellWidth() + this.getCellWidth() / 2, + secondaryDatePointTop + ); + points.push(point); + } + return points; + } +}