Skip to content

Commit 861d8a0

Browse files
authored
feat(gantt): support holiday options setting (#585)
* feat(gantt): support custom primary position * feat(gantt): add example custom day view * feat(gantt): add example custom day view * feat(gantt): remove bar set * feat(gantt): support holiday setting * feat(gantt): code review * feat(gantt): code review * feat(gantt): code review * feat(gantt): code review * feat(gantt): code review
1 parent 90fdff3 commit 861d8a0

File tree

15 files changed

+148
-110
lines changed

15 files changed

+148
-110
lines changed

example/src/app/gantt/gantt.component.html

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
     
1313
<span>基线对比:</span>
1414
<thy-switch class="baseline-switch" [(ngModel)]="isBaselineChecked" (ngModelChange)="switchChange()">基线对比 </thy-switch>
15+
&nbsp; &nbsp; &nbsp;
16+
<span>隐藏假期:</span>
17+
<thy-switch class="baseline-switch" [(ngModel)]="isHideHolidayChecked" (ngModelChange)="holidayChange()">隐藏假期 </thy-switch>
1518
</ng-template>
1619
<ng-template #headerOperation>
1720
<a href="https://github.com/worktile/ngx-gantt/blob/master/example/src/app/gantt" target="_blank">查看源码</a>

example/src/app/gantt/gantt.component.ts

Lines changed: 23 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { AfterViewInit, Component, HostBinding, OnInit, ViewChild } from '@angul
22
import {
33
GanttBarClickEvent,
44
GanttBaselineItem,
5+
GanttDate,
56
GanttDragEvent,
67
GanttItem,
78
GanttLineClickEvent,
@@ -15,6 +16,7 @@ import {
1516
GanttTableItemClickEvent,
1617
GanttToolbarOptions,
1718
GanttView,
19+
GanttViewOptions,
1820
GanttViewType,
1921
NgxGanttComponent
2022
} from 'ngx-gantt';
@@ -44,24 +46,26 @@ export class AppGanttExampleComponent implements OnInit, AfterViewInit {
4446
]
4547
};
4648

47-
viewType: GanttViewType = GanttViewType.month;
49+
viewType: GanttViewType = GanttViewType.day;
4850

49-
selectedViewType: GanttViewType = GanttViewType.month;
51+
selectedViewType: GanttViewType = GanttViewType.day;
5052

5153
isBaselineChecked = false;
5254

5355
isShowToolbarChecked = true;
5456

5557
loading = false;
5658

59+
isHideHolidayChecked = false;
60+
5761
items: GanttItem[] = [
5862
{ id: '000000', title: 'Task 0', start: 1627729997, end: 1627769997, draggable: false, linkable: false },
5963
// { id: '000001', title: 'Task 1', start: 1617361997, end: 1625483597, links: ['000003', '000004', '000000'], },
6064
{ id: '000001', title: 'Task 1', start: 1617361997, end: 1625483597, links: ['000003', '000004', '0000029'], draggable: false },
6165
{ id: '000002', title: 'Task 2', start: 1617361997, end: 1625483597, progress: 0.5, linkable: false },
6266
{ id: '000003', title: 'Task 3 (不可拖动)', start: 1628507597, end: 1633345997, itemDraggable: false },
6367
{ id: '000004', title: 'Task 4', start: 1624705997 },
64-
{ id: '000005', title: 'Task 5', start: 1628075597, end: 1629544397, color: '#709dc1' },
68+
{ id: '000005', title: 'Task 5', start: 1756628881, end: 1756801681, color: '#709dc1' },
6569
{ id: '000006', title: 'Task 6', start: 1641121997, end: 1645528397 },
6670
{ id: '000007', title: 'Task 7', start: 1639393997, end: 1640862797 },
6771
{ id: '000008', title: 'Task 8', end: 1628783999, color: '#709dc1' },
@@ -94,7 +98,12 @@ export class AppGanttExampleComponent implements OnInit, AfterViewInit {
9498
viewType: GanttViewType.day
9599
};
96100

97-
viewOptions = {};
101+
viewOptions: GanttViewOptions = {
102+
hoilday: {
103+
isHoliday: (date: GanttDate) => date.isWeekend(),
104+
hideHoliday: false
105+
}
106+
};
98107

99108
width = JSON.parse(localStorage.getItem(cacheKeys));
100109

@@ -231,4 +240,14 @@ export class AppGanttExampleComponent implements OnInit, AfterViewInit {
231240
this.width = width;
232241
localStorage.setItem(cacheKeys, JSON.stringify(width));
233242
}
243+
244+
holidayChange() {
245+
this.viewOptions = {
246+
...this.viewOptions,
247+
hoilday: {
248+
...this.viewOptions.hoilday,
249+
hideHoliday: this.isHideHolidayChecked
250+
}
251+
};
252+
}
234253
}

packages/gantt/src/class/date-point.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,9 @@
11
import { GanttDate } from '../utils/date';
22

33
export class GanttDatePoint {
4+
public leftX?: number;
5+
public rightX?: number;
6+
47
constructor(
58
public start: GanttDate,
69
public text: string,

packages/gantt/src/components/bar/bar-drag.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import { DragDrop, DragRef } from '@angular/cdk/drag-drop';
22
import { effect, ElementRef, Injectable, NgZone, OnDestroy, signal, WritableSignal } from '@angular/core';
3-
import { Subject, animationFrameScheduler, fromEvent, interval } from 'rxjs';
3+
import { animationFrameScheduler, fromEvent, interval, Subject } from 'rxjs';
44
import { takeUntil } from 'rxjs/operators';
55
import { GanttViewType } from '../../class';
66
import { GanttItemInternal } from '../../class/item';
@@ -378,8 +378,9 @@ export class GanttBarDrag implements OnDestroy {
378378
const currentX = this.item().refs.x + this.barDragMoveDistance + this.dragScrollDistance;
379379
const currentDate = this.ganttUpper.view.getDateByXPoint(currentX);
380380
const currentStartX = this.ganttUpper.view.getXPointByDate(currentDate);
381+
const currentEndDate = this.ganttUpper.view.getDateByXPoint(currentX + this.item().refs.width);
381382

382-
const diffs = this.ganttUpper.view.differenceByPrecisionUnit(this.item().end, this.item().start);
383+
const diffs = this.ganttUpper.view.differenceByPrecisionUnit(currentEndDate, currentDate);
383384

384385
let start = currentDate;
385386
let end = currentDate.add(diffs, this.ganttUpper.view?.options?.datePrecisionUnit);

packages/gantt/src/components/bar/bar.component.ts

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,30 @@
1+
import { NgTemplateOutlet } from '@angular/common';
12
import {
3+
AfterViewInit,
24
Component,
3-
OnInit,
4-
HostBinding,
55
ElementRef,
6+
EventEmitter,
7+
HostBinding,
8+
Inject,
9+
NgZone,
610
OnChanges,
711
OnDestroy,
8-
Inject,
9-
ViewChild,
12+
OnInit,
1013
Output,
11-
EventEmitter,
12-
AfterViewInit,
13-
ViewChildren,
1414
QueryList,
15-
NgZone,
16-
SimpleChanges
15+
SimpleChanges,
16+
ViewChild,
17+
ViewChildren
1718
} from '@angular/core';
1819
import { from, fromEvent, merge, Observable } from 'rxjs';
1920
import { startWith, switchMap, take, takeUntil } from 'rxjs/operators';
20-
import { GanttBarDrag } from './bar-drag';
21-
import { hexToRgb } from '../../utils/helpers';
22-
import { GanttDragContainer } from '../../gantt-drag-container';
23-
import { barBackground } from '../../gantt.styles';
2421
import { GanttBarClickEvent } from '../../class';
25-
import { GANTT_UPPER_TOKEN, GanttUpper } from '../../gantt-upper';
22+
import { GanttDragContainer } from '../../gantt-drag-container';
2623
import { GanttItemUpper } from '../../gantt-item-upper';
27-
import { NgTemplateOutlet } from '@angular/common';
24+
import { GANTT_UPPER_TOKEN, GanttUpper } from '../../gantt-upper';
25+
import { barBackground } from '../../gantt.styles';
26+
import { hexToRgb } from '../../utils/helpers';
27+
import { GanttBarDrag } from './bar-drag';
2828

2929
function linearGradient(sideOrCorner: string, color: string, stop: string) {
3030
return `linear-gradient(${sideOrCorner},${color} 0%,${stop} 40%)`;
@@ -123,10 +123,11 @@ export class NgxGanttBarComponent extends GanttItemUpper implements OnInit, Afte
123123
}
124124

125125
private setContentBackground() {
126+
let style: Partial<CSSStyleDeclaration> = { ...(this.item.barStyle || {}) };
127+
const contentElement = this.contentElementRef.nativeElement;
128+
126129
if (this.item.refs?.width) {
127-
const contentElement = this.contentElementRef.nativeElement;
128130
const color = this.item.color || barBackground;
129-
const style: Partial<CSSStyleDeclaration> = this.item.barStyle || {};
130131
const barElement = this.elementRef.nativeElement;
131132

132133
if (this.item.origin.start && this.item.origin.end) {
@@ -150,14 +151,14 @@ export class NgxGanttBarComponent extends GanttItemUpper implements OnInit, Afte
150151
if (this.item.progress >= 0) {
151152
const contentProgressElement = contentElement.querySelector('.gantt-bar-content-progress') as HTMLDivElement;
152153
style.background = hexToRgb(color, 0.3);
153-
style.borderRadius = '';
154154
contentProgressElement.style.background = color;
155155
}
156+
}
157+
style = Object.assign({}, style, this.item.barStyle || {});
156158

157-
for (const key in style) {
158-
if (style.hasOwnProperty(key)) {
159-
contentElement.style[key] = style[key];
160-
}
159+
for (const key in style) {
160+
if (style.hasOwnProperty(key)) {
161+
contentElement.style[key] = style[key];
161162
}
162163
}
163164
}

packages/gantt/src/components/calendar/grid/calendar-grid.component.html

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -29,14 +29,9 @@
2929
</g>
3030
}
3131
<g>
32-
@for (point of view.primaryDatePoints; track point.x) {
33-
<line
34-
[attr.x1]="($index + 1) * view.primaryWidth"
35-
[attr.x2]="($index + 1) * view.primaryWidth"
36-
[attr.y1]="0"
37-
[attr.y2]="mainHeight"
38-
class="primary-line"
39-
></line>
32+
@for (point of view.primaryDatePoints; track point?.x) {
33+
@let rightX = point?.rightX ?? ($index + 1) * view.primaryWidth;
34+
<line [attr.x1]="rightX" [attr.x2]="rightX" [attr.y1]="0" [attr.y2]="mainHeight" class="primary-line"></line>
4035
}
4136
</g>
4237
</g>

packages/gantt/src/components/calendar/header/calendar-header.component.html

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,9 @@
3939
}
4040

4141
<g>
42-
@for (point of view.primaryDatePoints; track point.x) {
43-
<line
44-
[attr.x1]="($index + 1) * view.primaryWidth"
45-
[attr.x2]="($index + 1) * view.primaryWidth"
46-
[attr.y1]="0"
47-
[attr.y2]="ganttUpper.styles.headerHeight"
48-
class="primary-line"
49-
></line>
42+
@for (point of view.primaryDatePoints; track point?.x) {
43+
@let rightX = point?.rightX ?? ($index + 1) * view.primaryWidth;
44+
<line [attr.x1]="rightX" [attr.x2]="rightX" [attr.y1]="0" [attr.y2]="ganttUpper.styles.headerHeight" class="primary-line"></line>
5045
}
5146
</g>
5247

packages/gantt/src/components/table/gantt-table.scss

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -193,6 +193,8 @@
193193
&::-webkit-scrollbar {
194194
display: none;
195195
}
196+
scrollbar-width: none;
197+
-ms-overflow-style: none;
196198
}
197199

198200
@include gantt-table-item();

packages/gantt/src/gantt-upper.ts

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,46 +1,46 @@
1+
import { BooleanInput, coerceBooleanProperty, coerceCssPixelValue } from '@angular/cdk/coercion';
2+
import { SelectionModel } from '@angular/cdk/collections';
13
import {
2-
Input,
3-
TemplateRef,
4-
Output,
5-
EventEmitter,
4+
ChangeDetectorRef,
65
ContentChild,
6+
Directive,
77
ElementRef,
8+
EventEmitter,
89
HostBinding,
9-
ChangeDetectorRef,
10-
NgZone,
11-
SimpleChanges,
1210
InjectionToken,
13-
Directive,
14-
OnInit,
15-
OnDestroy,
11+
Input,
12+
NgZone,
1613
OnChanges,
14+
OnDestroy,
15+
OnInit,
16+
Output,
17+
SimpleChanges,
18+
TemplateRef,
1719
inject
1820
} from '@angular/core';
19-
import { from, Subject } from 'rxjs';
20-
import { takeUntil, take, skip } from 'rxjs/operators';
21+
import { Subject, from } from 'rxjs';
22+
import { skip, take, takeUntil } from 'rxjs/operators';
2123
import {
22-
GanttItem,
23-
GanttGroup,
24-
GanttViewType,
25-
GanttLoadOnScrollEvent,
24+
GanttBarClickEvent,
2625
GanttDragEvent,
26+
GanttGroup,
2727
GanttGroupInternal,
28+
GanttItem,
2829
GanttItemInternal,
29-
GanttBarClickEvent,
3030
GanttLinkDragEvent,
31-
GanttToolbarOptions
31+
GanttLoadOnScrollEvent,
32+
GanttToolbarOptions,
33+
GanttViewType
3234
} from './class';
33-
import { GanttView, GanttViewOptions } from './views/view';
34-
import { createViewFactory } from './views/factory';
35-
import { GanttDate, getUnixTime } from './utils/date';
36-
import { uniqBy, flatten, recursiveItems, getFlatItems, Dictionary, keyBy } from './utils/helpers';
37-
import { GanttDragContainer } from './gantt-drag-container';
38-
import { GanttConfigService, GanttGlobalConfig, GanttStyleOptions, defaultConfig } from './gantt.config';
39-
import { GanttLinkOptions } from './class/link';
40-
import { SelectionModel } from '@angular/cdk/collections';
41-
import { BooleanInput, coerceBooleanProperty, coerceCssPixelValue } from '@angular/cdk/coercion';
4235
import { GanttBaselineItem, GanttBaselineItemInternal } from './class/baseline';
36+
import { GanttLinkOptions } from './class/link';
37+
import { GanttDragContainer } from './gantt-drag-container';
38+
import { GanttConfigService, GanttGlobalConfig, GanttStyleOptions } from './gantt.config';
4339
import { NgxGanttTableComponent } from './table/gantt-table.component';
40+
import { GanttDate, getUnixTime } from './utils/date';
41+
import { Dictionary, flatten, getFlatItems, keyBy, recursiveItems, uniqBy } from './utils/helpers';
42+
import { createViewFactory } from './views/factory';
43+
import { GanttView, GanttViewOptions } from './views/view';
4444

4545
@Directive()
4646
export abstract class GanttUpper implements OnChanges, OnInit, OnDestroy {

packages/gantt/src/public-api.ts

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -2,37 +2,37 @@
22
* Public API Surface of gantt
33
*/
44

5-
export * from './gantt.module';
6-
export * from './gantt-upper';
7-
export * from './root.component';
8-
export * from './gantt.component';
9-
export * from './table/gantt-table.component';
10-
export * from './table/gantt-column.component';
5+
export * from './class';
116
export * from './components/bar/bar.component';
12-
export * from './components/range/range.component';
137
export * from './components/baseline/baseline.component';
14-
export * from './components/toolbar/toolbar.component';
8+
export * from './components/calendar/grid/calendar-grid.component';
9+
export * from './components/calendar/header/calendar-header.component';
10+
export * from './components/drag-backdrop/drag-backdrop.component';
1511
export * from './components/loader/loader.component';
16-
export * from './utils/date';
17-
export * from './class';
18-
export * from './views/view';
12+
export * from './components/range/range.component';
13+
export * from './components/scrollbar/scrollbar.component';
14+
export * from './components/toolbar/toolbar.component';
15+
export * from './gantt-item-upper';
16+
export * from './gantt-print.service';
17+
export * from './gantt-upper';
18+
export * from './gantt.component';
19+
export * from './gantt.config';
20+
export * from './gantt.module';
21+
export * from './gantt.pipe';
1922
export {
20-
GanttI18nLocaleConfig,
21-
GanttI18nLocale,
22-
GANTT_I18N_LOCALE_TOKEN,
23-
zhHansLocale,
24-
zhHantLocale,
23+
deDeLocale,
2524
enUsLocale,
25+
GANTT_I18N_LOCALE_TOKEN,
26+
GanttI18nLocale,
27+
GanttI18nLocaleConfig,
2628
jaJpLocale,
27-
deDeLocale,
28-
ruRuLocale
29+
ruRuLocale,
30+
zhHansLocale,
31+
zhHantLocale
2932
} from './i18n';
33+
export * from './root.component';
34+
export * from './table/gantt-column.component';
35+
export * from './table/gantt-table.component';
36+
export * from './utils/date';
3037
export { registerView } from './views/factory';
31-
export * from './gantt-item-upper';
32-
export * from './gantt.pipe';
33-
export * from './gantt-print.service';
34-
export * from './gantt.config';
35-
export * from './components/calendar/header/calendar-header.component';
36-
export * from './components/calendar/grid/calendar-grid.component';
37-
export * from './components/drag-backdrop/drag-backdrop.component';
38-
export * from './components/scrollbar/scrollbar.component';
38+
export * from './views/view';

0 commit comments

Comments
 (0)