Skip to content

Commit 742f094

Browse files
committed
feat: gantt table component
1 parent a5082ec commit 742f094

17 files changed

+539
-438
lines changed
Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,19 @@
1-
<p>bar works!</p>
1+
<div class="gantt-bar-layer">
2+
<div class="drag-handles">
3+
<ng-container>
4+
<span class="handle"></span>
5+
<span class="handle"></span>
6+
</ng-container>
7+
</div>
8+
<div class="dependency-handles">
9+
<span class="handle"><span class="point"></span></span>
10+
<span class="handle"> <span class="point"></span></span>
11+
</div>
12+
</div>
13+
<div class="gantt-bar-border"></div>
14+
<div class="gantt-bar-content">
15+
<ng-template
16+
[ngTemplateOutlet]="template"
17+
[ngTemplateOutletContext]="{ item: item.origin, refs: item.refs }"
18+
></ng-template>
19+
</div>
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
$gantt-bar-layer-append-width: 32px;
2+
$gantt-bar-layer-append-height: 42px;
3+
$gantt-bar-dependency-height: 16px;
4+
$gantt-bar-dependency-drop-border: 5px;
5+
6+
@mixin dependency-handles {
7+
.dependency-handles {
8+
.handle {
9+
position: absolute;
10+
display: inline-block;
11+
cursor: pointer;
12+
width: $gantt-bar-dependency-height;
13+
height: $gantt-bar-dependency-height;
14+
display: flex;
15+
align-items: center;
16+
justify-content: center;
17+
z-index: 1001;
18+
19+
&:first-child {
20+
left: 0;
21+
top: 0;
22+
}
23+
24+
&:last-child {
25+
right: 0;
26+
bottom: 0;
27+
}
28+
29+
.point {
30+
color: #348fe4;
31+
width: 10px;
32+
height: 10px;
33+
border-radius: 50%;
34+
background: #348fe4;
35+
transition: 0.3 ease;
36+
37+
&:hover {
38+
width: 12px;
39+
height: 12px;
40+
}
41+
}
42+
}
43+
}
44+
}
45+
46+
@mixin drag-handles {
47+
.drag-handles {
48+
background: $gantt-bar-layer-bg;
49+
width: 100%;
50+
height: calc(100% - #{$gantt-bar-dependency-height} * 2);
51+
position: absolute;
52+
border-radius: 4px;
53+
top: $gantt-bar-dependency-height;
54+
box-shadow: 0 2px 5px 0 rgba(0, 0, 0, 0.15);
55+
56+
.handle {
57+
width: 15px;
58+
height: 100%;
59+
position: absolute;
60+
cursor: col-resize;
61+
display: flex;
62+
align-items: center;
63+
justify-content: center;
64+
65+
&:before,
66+
&:after {
67+
content: '';
68+
display: inline-block;
69+
width: 1px;
70+
height: $gantt-bar-handle-height;
71+
background: $gantt-bar-handle-color;
72+
}
73+
74+
&::before {
75+
margin-right: 2px;
76+
}
77+
78+
&:first-child {
79+
left: 0;
80+
}
81+
82+
&:last-child {
83+
right: 0;
84+
}
85+
}
86+
}
87+
}
88+
89+
@mixin active-bar {
90+
z-index: 1000;
91+
92+
.gantt-bar-layer {
93+
display: block;
94+
z-index: 1;
95+
}
96+
97+
.gantt-bar-content {
98+
z-index: 1;
99+
box-shadow: none;
100+
}
101+
102+
.cdk-drag {
103+
transition: none;
104+
}
105+
}
106+
107+
.gantt-bar {
108+
position: absolute;
109+
background-color: $gantt-item-bg-color;
110+
border-radius: 4px;
111+
z-index: 1;
112+
background: #348fe4;
113+
114+
.gantt-bar-layer {
115+
width: calc(100% + #{$gantt-bar-layer-append-width});
116+
height: calc(100% + #{$gantt-bar-layer-append-height});
117+
position: absolute;
118+
border-radius: 4px;
119+
left: $gantt-bar-layer-append-width / 2 * -1;
120+
top: $gantt-bar-layer-append-height / 2 * -1;
121+
display: none;
122+
@include drag-handles();
123+
@include dependency-handles();
124+
}
125+
126+
.gantt-bar-border {
127+
width: calc(100% + #{$gantt-bar-dependency-drop-border} * 2);
128+
height: calc(100% + #{$gantt-bar-dependency-drop-border} * 2);
129+
position: absolute;
130+
border-radius: 4px;
131+
left: $gantt-bar-dependency-drop-border * -1;
132+
top: $gantt-bar-dependency-drop-border * -1;
133+
display: none;
134+
background: #fff;
135+
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
136+
}
137+
138+
.gantt-bar-content {
139+
width: 100%;
140+
height: 100%;
141+
position: absolute;
142+
cursor: pointer;
143+
box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.1);
144+
border-radius: 4px;
145+
}
146+
147+
&-active {
148+
@include active-bar();
149+
}
150+
151+
&-dependency-drop {
152+
.gantt-bar-border {
153+
display: block;
154+
}
155+
156+
.gantt-bar-content {
157+
box-shadow: none;
158+
}
159+
}
160+
}
Lines changed: 54 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,61 @@
1-
import { Component, OnInit } from '@angular/core';
1+
import {
2+
Component,
3+
OnInit,
4+
Input,
5+
TemplateRef,
6+
HostBinding,
7+
ElementRef,
8+
OnChanges,
9+
SimpleChanges,
10+
OnDestroy,
11+
Inject,
12+
} from '@angular/core';
13+
import { GanttItemInternal } from '../class/item';
14+
import { GanttRef, GANTT_REF_TOKEN } from '../gantt-ref';
15+
import { takeUntil } from 'rxjs/operators';
16+
import { Subject } from 'rxjs';
217

318
@Component({
419
selector: 'gantt-bar',
520
templateUrl: './bar.component.html',
621
})
7-
export class GanttBarComponent implements OnInit {
8-
constructor() {}
22+
export class GanttBarComponent implements OnInit, OnChanges, OnDestroy {
23+
@Input() item: GanttItemInternal;
924

10-
ngOnInit() {}
25+
@Input() template: TemplateRef<any>;
26+
27+
@HostBinding('class.gantt-bar') ganttItemClass = true;
28+
29+
private firstChange = true;
30+
31+
private unsubscribe$ = new Subject();
32+
33+
constructor(private elementRef: ElementRef<HTMLDivElement>, @Inject(GANTT_REF_TOKEN) public ganttRef: GanttRef) {}
34+
35+
ngOnInit() {
36+
this.firstChange = false;
37+
38+
this.item.refs$.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
39+
this.updatePositions();
40+
});
41+
}
42+
43+
ngOnChanges(changes: SimpleChanges): void {
44+
if (!this.firstChange) {
45+
this.updatePositions();
46+
}
47+
}
48+
49+
private updatePositions() {
50+
const element = this.elementRef.nativeElement;
51+
element.style.left = this.item.refs.x + 'px';
52+
element.style.top = this.item.refs.y + 'px';
53+
element.style.width = this.item.refs.width + 'px';
54+
element.style.height = this.ganttRef.styles.barHeight + 'px';
55+
}
56+
57+
ngOnDestroy() {
58+
this.unsubscribe$.next();
59+
this.unsubscribe$.complete();
60+
}
1161
}

packages/gantt/src/calendar/calendar.component.html

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
<svg [attr.width]="view.width" [attr.height]="height">
2-
<g class="date">
2+
<g>
33
<text
44
class="primary-text"
55
*ngFor="let point of view.primaryDatePoints; trackBy: trackBy"
@@ -27,8 +27,18 @@
2727
class="primary-line"
2828
></line>
2929
</g>
30+
31+
<g>
32+
<line
33+
[attr.x1]="0"
34+
[attr.x2]="view.width"
35+
[attr.y1]="headerHeight"
36+
[attr.y2]="headerHeight"
37+
class="header-line"
38+
></line>
39+
</g>
3040
</g>
31-
<g class="date">
41+
<g>
3242
<g *ngIf="view.showTimeline">
3343
<line
3444
*ngFor="let point of view.secondaryDatePoints; let i = index; trackBy: trackBy"
Lines changed: 35 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,51 +1,54 @@
11
.gantt-calendar-overlay {
22
display: block;
33
height: 100%;
4+
overflow: hidden;
45

56
line {
67
shape-rendering: crispEdges;
78
}
89

9-
.date {
10-
.primary-text {
11-
fill: $gantt-date-primary-color;
12-
font-size: $gantt-date-primary-font-size;
13-
}
10+
.primary-text {
11+
fill: $gantt-date-primary-color;
12+
font-size: $gantt-date-primary-font-size;
13+
}
1414

15-
.secondary-text {
16-
fill: $gantt-date-secondary-color;
17-
font-size: $gantt-date-secondary-font-size;
15+
.secondary-text {
16+
fill: $gantt-date-secondary-color;
17+
font-size: $gantt-date-secondary-font-size;
1818

19-
&-weekend {
20-
fill: $gantt-date-secondary-weekend-color;
21-
}
19+
&-weekend {
20+
fill: $gantt-date-secondary-weekend-color;
2221
}
22+
}
2323

24-
.primary-text,
25-
.secondary-text {
26-
text-anchor: middle;
27-
}
24+
.primary-text,
25+
.secondary-text {
26+
text-anchor: middle;
27+
}
2828

29-
.primary-line {
30-
stroke: $gantt-border-color;
31-
}
29+
.primary-line {
30+
stroke: $gantt-border-color;
31+
}
3232

33-
.secondary-line {
34-
stroke-dasharray: 2px 3px;
35-
stroke: $gantt-date-secondary-border-color;
36-
}
33+
.secondary-line {
34+
stroke-dasharray: 2px 3px;
35+
stroke: $gantt-date-secondary-border-color;
36+
}
3737

38-
.secondary-backdrop {
39-
fill: $gantt-date-week-backdrop-bg;
40-
}
38+
.header-line {
39+
stroke: $gantt-border-color;
40+
}
4141

42-
.today-line-angle {
43-
fill: $gantt-date-today-color;
44-
}
42+
.secondary-backdrop {
43+
fill: $gantt-date-week-backdrop-bg;
44+
}
4545

46-
.today-line {
47-
stroke: $gantt-date-today-color;
48-
stroke-width: 2px;
49-
}
46+
.today-line-angle {
47+
fill: $gantt-date-today-color;
48+
}
49+
50+
.today-line {
51+
stroke: $gantt-date-today-color;
52+
stroke-width: 2px;
5053
}
5154
}

packages/gantt/src/calendar/calendar.component.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ import { GanttRef, GANTT_REF_TOKEN } from '../gantt-ref';
2121
export class GanttCalendarComponent implements OnInit, OnChanges, OnDestroy {
2222
public height = 500;
2323

24+
public headerHeight = 60;
25+
2426
public todayPoint: {
2527
x: number;
2628
angle: string;

0 commit comments

Comments
 (0)