From 1838f952141aa5ee2e8ce4389a58b11590f174e5 Mon Sep 17 00:00:00 2001 From: zhangwen <1062680993@qq.com> Date: Wed, 22 Jul 2020 15:11:01 +0800 Subject: [PATCH 1/2] feat: support gantt range and bar progress --- example/src/app/gantt/gantt.component.html | 1 - example/src/app/gantt/mocks.ts | 7 ++- packages/gantt/src/class/item.ts | 11 +++++ .../src/components/bar/bar.component.html | 1 + .../src/components/bar/bar.component.scss | 8 +++- .../gantt/src/components/bar/bar.component.ts | 7 +++ .../components/main/gantt-main.component.html | 10 +++- .../components/main/gantt-main.component.ts | 4 +- .../src/components/range/range.component.html | 5 ++ .../src/components/range/range.component.scss | 35 ++++++++++++++ .../src/components/range/range.component.ts | 48 +++++++++++++++++++ packages/gantt/src/gantt-upper.ts | 3 +- packages/gantt/src/gantt.module.ts | 3 +- packages/gantt/src/gantt.styles.ts | 6 ++- packages/gantt/src/styles/index.scss | 1 + 15 files changed, 141 insertions(+), 9 deletions(-) create mode 100644 packages/gantt/src/components/range/range.component.html create mode 100644 packages/gantt/src/components/range/range.component.scss create mode 100644 packages/gantt/src/components/range/range.component.ts diff --git a/example/src/app/gantt/gantt.component.html b/example/src/app/gantt/gantt.component.html index 4b29211d..d3a94d82 100644 --- a/example/src/app/gantt/gantt.component.html +++ b/example/src/app/gantt/gantt.component.html @@ -37,7 +37,6 @@ start="1514736000" end="1609430400" [items]="items" - [groups]="groups" [viewType]="options.viewType" [draggable]="options.draggable" [linkable]="options.linkable" diff --git a/example/src/app/gantt/mocks.ts b/example/src/app/gantt/mocks.ts index 9a81c20d..4e0353f6 100644 --- a/example/src/app/gantt/mocks.ts +++ b/example/src/app/gantt/mocks.ts @@ -28,7 +28,8 @@ export const mockItems = [ start: 1590035675, group_id: '00001', color: '#FF0000', - links: ['item-0301'], + type: 'range', + progress: 0.5, children: [ { id: 'item-child-0101', @@ -36,7 +37,9 @@ export const mockItems = [ start: 1590035675, group_id: '00001', color: '#FF0000', - linkable: false + linkable: false, + progress: 0.5, + barStyle: { border: `1px solid #FF0000` } } ] }, diff --git a/packages/gantt/src/class/item.ts b/packages/gantt/src/class/item.ts index 2dde2088..480512eb 100644 --- a/packages/gantt/src/class/item.ts +++ b/packages/gantt/src/class/item.ts @@ -7,6 +7,11 @@ interface GanttItemRefs { y: number; } +export enum GanttItemType { + bar = 'bar', + range = 'range' +} + export interface GanttItem { id: string; title: string; @@ -22,6 +27,8 @@ export interface GanttItem { color?: string; barStyle?: Partial; origin?: T; + type?: GanttItemType; + progress?: number; } export class GanttItemInternal { @@ -39,6 +46,8 @@ export class GanttItemInternal { expanded?: boolean; loading: boolean; children: GanttItemInternal[]; + type?: GanttItemType; + progress?: number; get refs() { return this.refs$.getValue(); @@ -61,6 +70,8 @@ export class GanttItemInternal { this.children = (item.children || []).map((subItem) => { return new GanttItemInternal(subItem); }); + this.type = this.origin.type || GanttItemType.bar; + this.progress = this.origin.progress; // fill one month when start or end is null if (item.start && !item.end) { this.end = new GanttDate(item.start).addMonths(1).endOfDay(); diff --git a/packages/gantt/src/components/bar/bar.component.html b/packages/gantt/src/components/bar/bar.component.html index a2018848..ffa2f91f 100644 --- a/packages/gantt/src/components/bar/bar.component.html +++ b/packages/gantt/src/components/bar/bar.component.html @@ -12,5 +12,6 @@
+
diff --git a/packages/gantt/src/components/bar/bar.component.scss b/packages/gantt/src/components/bar/bar.component.scss index e0f4d44f..d593199a 100644 --- a/packages/gantt/src/components/bar/bar.component.scss +++ b/packages/gantt/src/components/bar/bar.component.scss @@ -141,7 +141,13 @@ $gantt-bar-link-drop-border: 5px; box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1); border-radius: 4px; background: $gantt-bar-background-color; - + overflow: hidden; + .gantt-bar-content-progress { + position: absolute; + left: 0; + top: 0; + height: 100%; + } } diff --git a/packages/gantt/src/components/bar/bar.component.ts b/packages/gantt/src/components/bar/bar.component.ts index 0bae98d6..78512340 100644 --- a/packages/gantt/src/components/bar/bar.component.ts +++ b/packages/gantt/src/components/bar/bar.component.ts @@ -109,6 +109,13 @@ export class NgxGanttBarComponent implements OnInit, AfterViewInit, OnChanges, O style.background = linearGradient('to right', hexToRgb(color, 0.55), hexToRgb(color, 1)); style.borderRadius = '12.5px 4px 4px 12.5px'; } + if (this.item.progress >= 0) { + const contentProgressElement = contentElement.querySelector('.gantt-bar-content-progress') as HTMLDivElement; + style.background = hexToRgb(color, 0.3); + style.borderRadius = ''; + contentProgressElement.style.background = color; + } + for (const key in style) { if (style.hasOwnProperty(key)) { contentElement.style[key] = style[key]; diff --git a/packages/gantt/src/components/main/gantt-main.component.html b/packages/gantt/src/components/main/gantt-main.component.html index 7bcb4330..378ddad5 100644 --- a/packages/gantt/src/components/main/gantt-main.component.html +++ b/packages/gantt/src/components/main/gantt-main.component.html @@ -23,8 +23,16 @@
- + + + +
(); + ganttItemType = GanttItemType; + @HostBinding('class.gantt-main-container') ganttMainClass = true; constructor(@Inject(GANTT_UPPER_TOKEN) public ganttUpper: GanttUpper) {} diff --git a/packages/gantt/src/components/range/range.component.html b/packages/gantt/src/components/range/range.component.html new file mode 100644 index 00000000..d0328c27 --- /dev/null +++ b/packages/gantt/src/components/range/range.component.html @@ -0,0 +1,5 @@ +
+
+
+
+
diff --git a/packages/gantt/src/components/range/range.component.scss b/packages/gantt/src/components/range/range.component.scss new file mode 100644 index 00000000..b369e18d --- /dev/null +++ b/packages/gantt/src/components/range/range.component.scss @@ -0,0 +1,35 @@ +.gantt-range { + position: absolute; + z-index: 1; + .gantt-range-main { + height: 10px; + background: rgba(136, 136, 136, 0.2); + border: 1px solid #888; + border-radius: 4px 4px 0 0; + box-sizing: border-box; + position: relative; + .gantt-range-main-progress { + position: absolute; + left: 0; + top: 0; + height: 100%; + background: #888; + } + } + .gantt-range-triangle { + width: 0; + height: 0; + border-top: 7px solid #888; + position: absolute; + top: 10px; + + &.left { + border-right: 5px solid transparent; + left: 0; + } + &.right { + border-left: 5px solid transparent; + right: 0; + } + } +} diff --git a/packages/gantt/src/components/range/range.component.ts b/packages/gantt/src/components/range/range.component.ts new file mode 100644 index 00000000..d5d38230 --- /dev/null +++ b/packages/gantt/src/components/range/range.component.ts @@ -0,0 +1,48 @@ +import { Component, OnInit, Input, TemplateRef, HostBinding, ElementRef, OnChanges, OnDestroy, Inject } from '@angular/core'; +import { GanttItemInternal } from '../../class/item'; +import { takeUntil } from 'rxjs/operators'; +import { Subject } from 'rxjs'; +import { GANTT_UPPER_TOKEN, GanttUpper } from '../../gantt-upper'; +import { rangeHeight } from '../../gantt.styles'; + +@Component({ + selector: 'gantt-range', + templateUrl: './range.component.html' +}) +export class NgxGanttRangeComponent implements OnInit, OnChanges, OnDestroy { + @Input() item: GanttItemInternal; + + @HostBinding('class.gantt-range') ganttRangeClass = true; + + private firstChange = true; + + private unsubscribe$ = new Subject(); + + constructor(private elementRef: ElementRef, @Inject(GANTT_UPPER_TOKEN) public ganttUpper: GanttUpper) {} + + ngOnInit() { + this.firstChange = false; + this.item.refs$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => { + this.setPositions(); + }); + } + + ngOnChanges(): void { + if (!this.firstChange) { + this.setPositions(); + } + } + + private setPositions() { + const rangeElement = this.elementRef.nativeElement; + rangeElement.style.left = this.item.refs.x + 'px'; + rangeElement.style.top = this.item.refs.y + 'px'; + rangeElement.style.width = this.item.refs.width + 'px'; + rangeElement.style.height = rangeHeight + 'px'; + } + + ngOnDestroy() { + this.unsubscribe$.next(); + this.unsubscribe$.complete(); + } +} diff --git a/packages/gantt/src/gantt-upper.ts b/packages/gantt/src/gantt-upper.ts index 8efa43c0..426701a8 100644 --- a/packages/gantt/src/gantt-upper.ts +++ b/packages/gantt/src/gantt-upper.ts @@ -22,7 +22,8 @@ import { GanttGroupInternal, GanttItemInternal, GanttBarClickEvent, - GanttLinkDragEvent + GanttLinkDragEvent, + GanttItemType } from './class'; import { GanttView, GanttViewOptions } from './views/view'; import { createViewFactory } from './views/factory'; diff --git a/packages/gantt/src/gantt.module.ts b/packages/gantt/src/gantt.module.ts index ea50fc80..b488332a 100644 --- a/packages/gantt/src/gantt.module.ts +++ b/packages/gantt/src/gantt.module.ts @@ -14,6 +14,7 @@ import { GanttIconComponent } from './components/icon/icon.component'; import { GanttDragBackdropComponent } from './components/drag-backdrop/drag-backdrop.component'; import { GanttLinksComponent } from './components/links/links.component'; import { NgxGanttRootComponent } from './root.component'; +import { NgxGanttRangeComponent } from './components/range/range.component'; @NgModule({ imports: [CommonModule], @@ -37,7 +38,7 @@ import { NgxGanttRootComponent } from './root.component'; NgxGanttBarComponent, GanttIconComponent, GanttDragBackdropComponent, - + NgxGanttRangeComponent, NgxGanttRootComponent ], providers: [] diff --git a/packages/gantt/src/gantt.styles.ts b/packages/gantt/src/gantt.styles.ts index 49276146..9636556b 100644 --- a/packages/gantt/src/gantt.styles.ts +++ b/packages/gantt/src/gantt.styles.ts @@ -1,6 +1,6 @@ export const defaultStyles = { lineHeight: 44, - barHeight: 22, + barHeight: 22 }; export const headerHeight = 44; @@ -16,3 +16,7 @@ export const sideMaxWidth = 600; export const sideMinWidth = 400; export const barBackground = '#348fe4'; + +export const rangeHeight = 17; + + diff --git a/packages/gantt/src/styles/index.scss b/packages/gantt/src/styles/index.scss index 95093b27..d97fccac 100644 --- a/packages/gantt/src/styles/index.scss +++ b/packages/gantt/src/styles/index.scss @@ -5,5 +5,6 @@ @import '../components/calendar/calendar.component.scss'; @import '../components/drag-backdrop/drag-backdrop.component.scss'; @import '../components/bar/bar.component.scss'; +@import '../components/range/range.component.scss'; @import '../components/icon/icon.component.scss'; @import '../components/links/links.component.scss'; From 376f70233b2ea95223c74be686d05d5223cb0f98 Mon Sep 17 00:00:00 2001 From: zhangwen <1062680993@qq.com> Date: Wed, 22 Jul 2020 17:37:46 +0800 Subject: [PATCH 2/2] fix: add base GanttItemUpper and range demo --- .docgenirc.js | 9 ++ example/src/app/app-routing.module.ts | 5 + example/src/app/app.module.ts | 5 +- .../app/configuration/parameters/api/zh-cn.js | 12 ++ .../gantt-range/gantt-range.component.html | 61 +++++++ .../app/gantt-range/gantt-range.component.ts | 62 ++++++++ example/src/app/gantt-range/mocks.ts | 150 ++++++++++++++++++ example/src/app/gantt/gantt.component.html | 1 + example/src/app/gantt/mocks.ts | 6 +- .../gantt/src/components/bar/bar.component.ts | 45 ++---- .../src/components/range/range.component.ts | 39 ++--- packages/gantt/src/gantt-item-upper.ts | 47 ++++++ packages/gantt/src/gantt-upper.ts | 3 +- packages/gantt/src/public-api.ts | 1 + 14 files changed, 373 insertions(+), 73 deletions(-) create mode 100644 example/src/app/gantt-range/gantt-range.component.html create mode 100644 example/src/app/gantt-range/gantt-range.component.ts create mode 100644 example/src/app/gantt-range/mocks.ts create mode 100644 packages/gantt/src/gantt-item-upper.ts diff --git a/.docgenirc.js b/.docgenirc.js index 6fe7e810..a95a4d5d 100644 --- a/.docgenirc.js +++ b/.docgenirc.js @@ -27,6 +27,15 @@ module.exports = { } } }, + { + title: '区间展示', + path: 'range', + locales: { + 'en-us': { + title: 'Range' + } + } + }, { title: '配置', path: 'configuration', diff --git a/example/src/app/app-routing.module.ts b/example/src/app/app-routing.module.ts index 22c4f2e5..63b69c47 100644 --- a/example/src/app/app-routing.module.ts +++ b/example/src/app/app-routing.module.ts @@ -2,6 +2,7 @@ import { NgModule } from '@angular/core'; import { Routes, RouterModule } from '@angular/router'; import { AppGanttExampleComponent } from './gantt/gantt.component'; import { AppGanttFlatExampleComponent } from './gantt-flat/flat.component'; +import { AppGanttRangeExampleComponent } from './gantt-range/gantt-range.component'; const routes: Routes = [ { @@ -12,6 +13,10 @@ const routes: Routes = [ path: 'flat', component: AppGanttFlatExampleComponent, }, + { + path: 'range', + component: AppGanttRangeExampleComponent + } ]; @NgModule({ diff --git a/example/src/app/app.module.ts b/example/src/app/app.module.ts index eb8540f1..7ac8ddcc 100644 --- a/example/src/app/app.module.ts +++ b/example/src/app/app.module.ts @@ -11,9 +11,10 @@ import { AppRoutingModule } from './app-routing.module'; import { CommonModule } from '@angular/common'; import { AppGanttFlatExampleComponent } from './gantt-flat/flat.component'; import { EXAMPLE_MODULES } from './content/example-modules'; +import { AppGanttRangeExampleComponent } from './gantt-range/gantt-range.component'; @NgModule({ - declarations: [AppComponent, AppGanttExampleComponent, AppGanttFlatExampleComponent], + declarations: [AppComponent, AppGanttExampleComponent, AppGanttFlatExampleComponent, AppGanttRangeExampleComponent], imports: [CommonModule, DocgeniTemplateModule, NgxGanttModule, AppRoutingModule, RouterModule.forRoot([...routes]), ...EXAMPLE_MODULES], providers: [ { provide: APP_INITIALIZER, useFactory: initializeDocgeniSite, deps: [GlobalContext], multi: true }, @@ -23,6 +24,6 @@ import { EXAMPLE_MODULES } from './content/example-modules'; useValue: config } ], - bootstrap: [AppComponent], + bootstrap: [AppComponent] }) export class AppModule {} diff --git a/example/src/app/configuration/parameters/api/zh-cn.js b/example/src/app/configuration/parameters/api/zh-cn.js index b1ab2999..f30faace 100644 --- a/example/src/app/configuration/parameters/api/zh-cn.js +++ b/example/src/app/configuration/parameters/api/zh-cn.js @@ -193,6 +193,18 @@ module.exports = [ description: `设置原始数据`, type: 'T', default: '' + }, + { + name: 'type', + description: `数据展示方式(区间展示和普通展示)`, + type: 'GanttItemType', + default: '' + }, + { + name: 'progress', + description: `进度`, + type: 'number', + default: '' } ] }, diff --git a/example/src/app/gantt-range/gantt-range.component.html b/example/src/app/gantt-range/gantt-range.component.html new file mode 100644 index 00000000..30906c73 --- /dev/null +++ b/example/src/app/gantt-range/gantt-range.component.html @@ -0,0 +1,61 @@ +
+
+ 视图: + + + + + +
+
+ 是否可拖拽: + + + +
+ +
+ + + +
+
+ + + +
+
+
+ + + + + {{ item.title }} + + + + 开始时间 + + {{ item.start * 1000 | date: 'yyyy-MM-dd' }} + + + + + {{ item.end * 1000 | date: 'yyyy-MM-dd' }} + + + + +
diff --git a/example/src/app/gantt-range/gantt-range.component.ts b/example/src/app/gantt-range/gantt-range.component.ts new file mode 100644 index 00000000..83b1302f --- /dev/null +++ b/example/src/app/gantt-range/gantt-range.component.ts @@ -0,0 +1,62 @@ +import { Component, OnInit, HostBinding } from '@angular/core'; +import { mockItems } from './mocks'; +import { + GanttBarClickEvent, + GanttViewType, + GanttDragEvent, + GanttLoadOnScrollEvent, + GanttLineClickEvent, + GanttLinkDragEvent, + GanttItem, + GanttViewOptions, + GanttDate +} from 'ngx-gantt'; +import { of } from 'rxjs'; +import { delay } from 'rxjs/operators'; +@Component({ + selector: 'app-gantt-range-example', + templateUrl: './gantt-range.component.html' +}) +export class AppGanttRangeExampleComponent implements OnInit { + items = mockItems; + + options = { + viewType: GanttViewType.month, + draggable: true, + async: true, + childrenResolve: this.getChildren.bind(this) + }; + + viewOptions: GanttViewOptions = { + start: new GanttDate(new Date('2020-3-1')), + end: new GanttDate(new Date('2020-6-30')) + }; + + @HostBinding('class.gantt-demo') class = true; + + constructor() {} + + ngOnInit(): void {} + + barClick(event: GanttBarClickEvent) { + console.log(event); + } + + dragEnded(event: GanttDragEvent) { + this.items = [...this.items]; + } + + loadOnScroll(event: GanttLoadOnScrollEvent) {} + + getChildren(item: GanttItem) { + return of([ + { + id: new Date().getTime(), + title: new Date().getTime(), + start: Math.floor(new Date().getTime() / 1000), + draggable: true, + linkable: false + } + ]).pipe(delay(1000)); + } +} diff --git a/example/src/app/gantt-range/mocks.ts b/example/src/app/gantt-range/mocks.ts new file mode 100644 index 00000000..1982d4d2 --- /dev/null +++ b/example/src/app/gantt-range/mocks.ts @@ -0,0 +1,150 @@ +export const mockItems = [ + { + id: 'item-0101', + title: 'VERSION 0101', + start: 1590035675, + group_id: '00001', + color: '#FF0000', + type: 'range', + progress: 0.5, + children: [ + { + id: 'item-child-0101', + title: 'VERSION Children 0101', + start: 1590035675, + group_id: '00001', + color: '#FF0000', + linkable: false, + progress: 0.5, + barStyle: { border: `1px solid #FF0000` } + } + ] + }, + { + id: 'item-0102', + title: 'VERSION 0102', + start: 1590935675, + end: 1591318400, + color: '#9ACD32', + group_id: '00001', + expandable: true + }, + { + id: 'item-0103', + title: 'VERSION 0103', + end: 1592018400, + group_id: '00001' + }, + { + id: 'item-0104', + title: 'VERSION 0104', + group_id: '00001', + links: ['item-0301'] + }, + { + id: 'item-0201', + title: 'VERSION 0201', + group_id: '00002' + }, + { + id: 'item-0202', + title: 'VERSION 0202', + start: 1591035675, + end: 1593018400, + group_id: '00002', + links: ['item-0203'], + color: 'rgb(52, 143, 228, 0.5)', + barStyle: { + border: '1px solid rgb(52, 143, 228)' + } + }, + { + id: 'item-0203', + title: 'VERSION 0203', + start: 1590235675, + end: 1591718400, + group_id: '00002', + links: ['item-0204'], + progress: 0.6, + barStyle: { border: `1px solid rgb(52, 143, 228)` } + }, + { + id: 'item-0204', + title: 'VERSION 0204', + start: 1591035675, + end: 1592418400, + group_id: '00002', + links: ['item-0301', 'item-0402'] + }, + + { + id: 'item-0301', + title: 'VERSION 0301', + start: 1596035675, + end: 1599018400, + group_id: '00003' + }, + { + id: 'item-0302', + title: 'VERSION 0302', + start: 1592035675, + end: 1598018400, + group_id: '00003' + }, + { + id: 'item-0303', + title: 'VERSION 0303', + start: 1590135675, + end: 1594018400, + group_id: '00003' + }, + { + id: 'item-0401', + title: 'VERSION 0401', + start: 1589035675, + end: 1594018400, + group_id: '00004' + }, + { + id: 'item-0402', + title: 'VERSION 0402', + start: 1596035675, + end: 1599918400, + group_id: '00004' + }, + { + id: 'item-0403', + title: 'VERSION 0403', + start: 1593035675, + end: 1599018400, + group_id: '00004' + }, + { + id: 'item-0404', + title: 'VERSION 0404', + start: 1591035675, + end: 1592918400, + group_id: '00004' + }, + { + id: 'item-0501', + title: 'VERSION 0501', + start: 1599935675, + end: 1602018400, + group_id: '00005' + }, + { + id: 'item-0502', + title: 'VERSION 0502', + start: 1591035675, + end: 1594018400, + group_id: '00005' + }, + { + id: 'item-0503', + title: 'VERSION 0503', + start: 1595035675, + end: 1599018400, + group_id: '00005' + } +]; diff --git a/example/src/app/gantt/gantt.component.html b/example/src/app/gantt/gantt.component.html index d3a94d82..00e92be0 100644 --- a/example/src/app/gantt/gantt.component.html +++ b/example/src/app/gantt/gantt.component.html @@ -36,6 +36,7 @@ #gantt start="1514736000" end="1609430400" + [groups]="groups" [items]="items" [viewType]="options.viewType" [draggable]="options.draggable" diff --git a/example/src/app/gantt/mocks.ts b/example/src/app/gantt/mocks.ts index 4e0353f6..ee5ff506 100644 --- a/example/src/app/gantt/mocks.ts +++ b/example/src/app/gantt/mocks.ts @@ -28,8 +28,6 @@ export const mockItems = [ start: 1590035675, group_id: '00001', color: '#FF0000', - type: 'range', - progress: 0.5, children: [ { id: 'item-child-0101', @@ -37,9 +35,7 @@ export const mockItems = [ start: 1590035675, group_id: '00001', color: '#FF0000', - linkable: false, - progress: 0.5, - barStyle: { border: `1px solid #FF0000` } + linkable: false } ] }, diff --git a/packages/gantt/src/components/bar/bar.component.ts b/packages/gantt/src/components/bar/bar.component.ts index 78512340..ec167b4b 100644 --- a/packages/gantt/src/components/bar/bar.component.ts +++ b/packages/gantt/src/components/bar/bar.component.ts @@ -6,24 +6,21 @@ import { HostBinding, ElementRef, OnChanges, - SimpleChanges, OnDestroy, Inject, - NgZone, ViewChild, Output, EventEmitter, AfterViewInit } from '@angular/core'; -import { GanttItemInternal } from '../../class/item'; -import { takeUntil, take, startWith } from 'rxjs/operators'; -import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; import { GanttBarDrag } from './bar-drag'; import { hexToRgb } from '../../utils/helpers'; import { GanttDragContainer } from '../../gantt-drag-container'; import { barBackground } from '../../gantt.styles'; import { GanttBarClickEvent } from '../../class'; import { GANTT_UPPER_TOKEN, GanttUpper } from '../../gantt-upper'; +import { GanttItemUpper } from '../../gantt-item-upper'; function linearGradient(sideOrCorner: string, color: string, stop: string) { return `linear-gradient(${sideOrCorner},${color} 0%,${stop} 40%)`; @@ -34,9 +31,7 @@ function linearGradient(sideOrCorner: string, color: string, stop: string) { templateUrl: './bar.component.html', providers: [GanttBarDrag] }) -export class NgxGanttBarComponent implements OnInit, AfterViewInit, OnChanges, OnDestroy { - @Input() item: GanttItemInternal; - +export class NgxGanttBarComponent extends GanttItemUpper implements OnInit, AfterViewInit, OnChanges, OnDestroy { @Input() template: TemplateRef; @Output() barClick = new EventEmitter(); @@ -45,26 +40,19 @@ export class NgxGanttBarComponent implements OnInit, AfterViewInit, OnChanges, O @HostBinding('class.gantt-bar') ganttItemClass = true; - private firstChange = true; - color = 'red'; - private unsubscribe$ = new Subject(); - constructor( - private elementRef: ElementRef, - private ngZone: NgZone, private dragContainer: GanttDragContainer, private drag: GanttBarDrag, + elementRef: ElementRef, @Inject(GANTT_UPPER_TOKEN) public ganttUpper: GanttUpper - ) {} + ) { + super(elementRef, ganttUpper); + } ngOnInit() { - this.firstChange = false; - - this.item.refs$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => { - this.setPositions(); - }); + super.onInit(); this.dragContainer.dragEnded.pipe(takeUntil(this.unsubscribe$)).subscribe(() => { this.setContentBackground(); }); @@ -75,24 +63,14 @@ export class NgxGanttBarComponent implements OnInit, AfterViewInit, OnChanges, O this.setContentBackground(); } - ngOnChanges(changes: SimpleChanges): void { - if (!this.firstChange) { - this.setPositions(); - } + ngOnChanges(): void { + super.onChanges(); } onBarClick(event: Event) { this.barClick.emit({ event, item: this.item.origin }); } - private setPositions() { - const barElement = this.elementRef.nativeElement; - barElement.style.left = this.item.refs.x + 'px'; - barElement.style.top = this.item.refs.y + 'px'; - barElement.style.width = this.item.refs.width + 'px'; - barElement.style.height = this.ganttUpper.styles.barHeight + 'px'; - } - private setContentBackground() { const contentElement = this.contentElementRef.nativeElement; const color = this.item.color || barBackground; @@ -124,7 +102,6 @@ export class NgxGanttBarComponent implements OnInit, AfterViewInit, OnChanges, O } ngOnDestroy() { - this.unsubscribe$.next(); - this.unsubscribe$.complete(); + super.onDestroy(); } } diff --git a/packages/gantt/src/components/range/range.component.ts b/packages/gantt/src/components/range/range.component.ts index d5d38230..5325efd4 100644 --- a/packages/gantt/src/components/range/range.component.ts +++ b/packages/gantt/src/components/range/range.component.ts @@ -1,48 +1,27 @@ -import { Component, OnInit, Input, TemplateRef, HostBinding, ElementRef, OnChanges, OnDestroy, Inject } from '@angular/core'; -import { GanttItemInternal } from '../../class/item'; -import { takeUntil } from 'rxjs/operators'; -import { Subject } from 'rxjs'; +import { Component, OnInit, HostBinding, ElementRef, OnChanges, OnDestroy, Inject } from '@angular/core'; import { GANTT_UPPER_TOKEN, GanttUpper } from '../../gantt-upper'; -import { rangeHeight } from '../../gantt.styles'; +import { GanttItemUpper } from '../../gantt-item-upper'; @Component({ selector: 'gantt-range', templateUrl: './range.component.html' }) -export class NgxGanttRangeComponent implements OnInit, OnChanges, OnDestroy { - @Input() item: GanttItemInternal; - +export class NgxGanttRangeComponent extends GanttItemUpper implements OnInit, OnChanges, OnDestroy { @HostBinding('class.gantt-range') ganttRangeClass = true; - private firstChange = true; - - private unsubscribe$ = new Subject(); - - constructor(private elementRef: ElementRef, @Inject(GANTT_UPPER_TOKEN) public ganttUpper: GanttUpper) {} + constructor(elementRef: ElementRef, @Inject(GANTT_UPPER_TOKEN) ganttUpper: GanttUpper) { + super(elementRef, ganttUpper); + } ngOnInit() { - this.firstChange = false; - this.item.refs$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => { - this.setPositions(); - }); + super.onInit(); } ngOnChanges(): void { - if (!this.firstChange) { - this.setPositions(); - } - } - - private setPositions() { - const rangeElement = this.elementRef.nativeElement; - rangeElement.style.left = this.item.refs.x + 'px'; - rangeElement.style.top = this.item.refs.y + 'px'; - rangeElement.style.width = this.item.refs.width + 'px'; - rangeElement.style.height = rangeHeight + 'px'; + super.onChanges(); } ngOnDestroy() { - this.unsubscribe$.next(); - this.unsubscribe$.complete(); + super.onDestroy(); } } diff --git a/packages/gantt/src/gantt-item-upper.ts b/packages/gantt/src/gantt-item-upper.ts new file mode 100644 index 00000000..93208fdf --- /dev/null +++ b/packages/gantt/src/gantt-item-upper.ts @@ -0,0 +1,47 @@ +import { Input, ElementRef, Inject } from '@angular/core'; +import { GanttItemInternal, GanttItemType } from './class'; +import { Subject } from 'rxjs'; +import { takeUntil } from 'rxjs/operators'; +import { rangeHeight } from './gantt.styles'; +import { GANTT_UPPER_TOKEN, GanttUpper } from './gantt-upper'; + +export abstract class GanttItemUpper { + @Input() item: GanttItemInternal; + + public firstChange = true; + + public unsubscribe$ = new Subject(); + + constructor(protected elementRef: ElementRef, @Inject(GANTT_UPPER_TOKEN) protected ganttUpper: GanttUpper) {} + + onInit() { + this.firstChange = false; + this.item.refs$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => { + this.setPositions(); + }); + } + + onChanges(): void { + if (!this.firstChange) { + this.setPositions(); + } + } + + private setPositions() { + const itemElement = this.elementRef.nativeElement; + itemElement.style.left = this.item.refs.x + 'px'; + itemElement.style.top = this.item.refs.y + 'px'; + itemElement.style.width = this.item.refs.width + 'px'; + if (this.item.type === GanttItemType.bar) { + itemElement.style.height = this.ganttUpper.styles.barHeight + 'px'; + } else if (this.item.type === GanttItemType.range) { + itemElement.style.height = rangeHeight + 'px'; + } else { + } + } + + onDestroy() { + this.unsubscribe$.next(); + this.unsubscribe$.complete(); + } +} diff --git a/packages/gantt/src/gantt-upper.ts b/packages/gantt/src/gantt-upper.ts index 426701a8..8efa43c0 100644 --- a/packages/gantt/src/gantt-upper.ts +++ b/packages/gantt/src/gantt-upper.ts @@ -22,8 +22,7 @@ import { GanttGroupInternal, GanttItemInternal, GanttBarClickEvent, - GanttLinkDragEvent, - GanttItemType + GanttLinkDragEvent } from './class'; import { GanttView, GanttViewOptions } from './views/view'; import { createViewFactory } from './views/factory'; diff --git a/packages/gantt/src/public-api.ts b/packages/gantt/src/public-api.ts index c3168525..6b97984d 100644 --- a/packages/gantt/src/public-api.ts +++ b/packages/gantt/src/public-api.ts @@ -12,3 +12,4 @@ export * from './flat/gantt-flat.component'; export * from './utils/date'; export * from './class'; export * from './views/view'; +export * from './gantt-item-upper';