@syncfusion/ej2-gantt 19.4.55 → 20.1.47-1460716
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1072 -1047
- package/README.md +75 -75
- package/dist/ej2-gantt.umd.min.js +1 -10
- package/dist/ej2-gantt.umd.min.js.map +1 -1
- package/dist/es6/ej2-gantt.es2015.js +341 -240
- package/dist/es6/ej2-gantt.es2015.js.map +1 -1
- package/dist/es6/ej2-gantt.es5.js +713 -598
- package/dist/es6/ej2-gantt.es5.js.map +1 -1
- package/dist/global/ej2-gantt.min.js +1 -10
- package/dist/global/ej2-gantt.min.js.map +1 -1
- package/dist/global/index.d.ts +0 -9
- package/dist/ts/components.ts +4 -0
- package/dist/ts/gantt/actions/actions.ts +18 -0
- package/dist/ts/gantt/actions/cell-edit.ts +606 -0
- package/dist/ts/gantt/actions/chart-scroll.ts +167 -0
- package/dist/ts/gantt/actions/column-menu.ts +35 -0
- package/dist/ts/gantt/actions/column-reorder.ts +52 -0
- package/dist/ts/gantt/actions/column-resize.ts +52 -0
- package/dist/ts/gantt/actions/connector-line-edit.ts +829 -0
- package/dist/ts/gantt/actions/context-menu.ts +754 -0
- package/dist/ts/gantt/actions/day-markers.ts +80 -0
- package/dist/ts/gantt/actions/dependency.ts +692 -0
- package/dist/ts/gantt/actions/dialog-edit.ts +2208 -0
- package/dist/ts/gantt/actions/edit.ts +3499 -0
- package/dist/ts/gantt/actions/excel-export.ts +61 -0
- package/dist/ts/gantt/actions/filter.ts +302 -0
- package/dist/ts/gantt/actions/keyboard.ts +306 -0
- package/dist/ts/gantt/actions/pdf-export.ts +214 -0
- package/dist/ts/gantt/actions/rowdragdrop.ts +839 -0
- package/dist/ts/gantt/actions/selection.ts +536 -0
- package/dist/ts/gantt/actions/sort.ts +98 -0
- package/dist/ts/gantt/actions/taskbar-edit.ts +1940 -0
- package/dist/ts/gantt/actions/toolbar.ts +489 -0
- package/dist/ts/gantt/actions/virtual-scroll.ts +60 -0
- package/dist/ts/gantt/base/common.ts +9 -0
- package/dist/ts/gantt/base/constant.ts +13 -0
- package/dist/ts/gantt/base/css-constants.ts +148 -0
- package/dist/ts/gantt/base/date-processor.ts +1257 -0
- package/dist/ts/gantt/base/enum.ts +372 -0
- package/dist/ts/gantt/base/gantt-chart.ts +1248 -0
- package/dist/ts/gantt/base/gantt.ts +4069 -0
- package/dist/ts/gantt/base/interface.ts +955 -0
- package/dist/ts/gantt/base/splitter.ts +174 -0
- package/dist/ts/gantt/base/task-processor.ts +2217 -0
- package/dist/ts/gantt/base/tree-grid.ts +694 -0
- package/dist/ts/gantt/base/utils.ts +208 -0
- package/dist/ts/gantt/export/export-helper.ts +552 -0
- package/dist/ts/gantt/export/pdf-base/dictionary.ts +152 -0
- package/dist/ts/gantt/export/pdf-base/pdf-borders.ts +277 -0
- package/dist/ts/gantt/export/pdf-base/pdf-grid-table.ts +901 -0
- package/dist/ts/gantt/export/pdf-base/pdf-style/gantt-theme.ts +131 -0
- package/dist/ts/gantt/export/pdf-base/pdf-style/style.ts +91 -0
- package/dist/ts/gantt/export/pdf-base/treegrid-layouter.ts +414 -0
- package/dist/ts/gantt/export/pdf-connector-line.ts +422 -0
- package/dist/ts/gantt/export/pdf-gantt.ts +282 -0
- package/dist/ts/gantt/export/pdf-taskbar.ts +395 -0
- package/dist/ts/gantt/export/pdf-timeline.ts +202 -0
- package/dist/ts/gantt/export/pdf-treegrid.ts +406 -0
- package/dist/ts/gantt/models/add-dialog-field-settings.ts +33 -0
- package/dist/ts/gantt/models/column.ts +464 -0
- package/dist/ts/gantt/models/day-working-time.ts +22 -0
- package/dist/ts/gantt/models/edit-dialog-field-settings.ts +33 -0
- package/dist/ts/gantt/models/edit-settings.ts +79 -0
- package/dist/ts/gantt/models/event-marker.ts +27 -0
- package/dist/ts/gantt/models/filter-settings.ts +53 -0
- package/dist/ts/gantt/models/holiday.ts +34 -0
- package/dist/ts/gantt/models/label-settings.ts +30 -0
- package/dist/ts/gantt/models/models.ts +36 -0
- package/dist/ts/gantt/models/resource-fields.ts +38 -0
- package/dist/ts/gantt/models/search-settings.ts +77 -0
- package/dist/ts/gantt/models/selection-settings.ts +56 -0
- package/dist/ts/gantt/models/sort-settings.ts +50 -0
- package/dist/ts/gantt/models/splitter-settings.ts +47 -0
- package/dist/ts/gantt/models/task-fields.ts +171 -0
- package/dist/ts/gantt/models/timeline-settings.ts +112 -0
- package/dist/ts/gantt/models/tooltip-settings.ts +46 -0
- package/dist/ts/gantt/renderer/chart-rows.ts +1838 -0
- package/dist/ts/gantt/renderer/connector-line.ts +1025 -0
- package/dist/ts/gantt/renderer/edit-tooltip.ts +228 -0
- package/dist/ts/gantt/renderer/event-marker.ts +96 -0
- package/dist/ts/gantt/renderer/nonworking-day.ts +205 -0
- package/dist/ts/gantt/renderer/render.ts +5 -0
- package/dist/ts/gantt/renderer/timeline.ts +1397 -0
- package/dist/ts/gantt/renderer/tooltip.ts +450 -0
- package/dist/ts/gantt/renderer/virtual-content-render.ts +50 -0
- package/license +9 -9
- package/package.json +80 -80
- package/src/gantt/actions/cell-edit.js +2 -1
- package/src/gantt/actions/dialog-edit.js +2 -1
- package/src/gantt/actions/edit.js +36 -9
- package/src/gantt/actions/rowdragdrop.js +37 -15
- package/src/gantt/actions/selection.js +3 -2
- package/src/gantt/actions/taskbar-edit.js +24 -24
- package/src/gantt/base/date-processor.js +0 -1
- package/src/gantt/base/gantt-chart.js +36 -5
- package/src/gantt/base/gantt-model.d.ts +779 -779
- package/src/gantt/base/gantt.d.ts +27 -27
- package/src/gantt/base/gantt.js +35 -76
- package/src/gantt/base/splitter.js +1 -0
- package/src/gantt/base/task-processor.js +13 -13
- package/src/gantt/base/tree-grid.js +3 -1
- package/src/gantt/export/pdf-base/treegrid-layouter.js +13 -13
- package/src/gantt/export/pdf-connector-line.js +11 -11
- package/src/gantt/export/pdf-gantt.js +24 -24
- package/src/gantt/export/pdf-taskbar.js +11 -11
- package/src/gantt/export/pdf-treegrid.js +13 -13
- package/src/gantt/models/add-dialog-field-settings-model.d.ts +21 -21
- package/src/gantt/models/add-dialog-field-settings.js +19 -19
- package/src/gantt/models/day-working-time-model.d.ts +11 -11
- package/src/gantt/models/day-working-time.js +19 -19
- package/src/gantt/models/edit-dialog-field-settings-model.d.ts +21 -21
- package/src/gantt/models/edit-dialog-field-settings.js +19 -19
- package/src/gantt/models/edit-settings-model.d.ts +50 -50
- package/src/gantt/models/edit-settings.js +19 -19
- package/src/gantt/models/event-marker-model.d.ts +16 -16
- package/src/gantt/models/event-marker.js +19 -19
- package/src/gantt/models/filter-settings-model.d.ts +34 -34
- package/src/gantt/models/filter-settings.js +19 -19
- package/src/gantt/models/holiday-model.d.ts +21 -21
- package/src/gantt/models/holiday.js +19 -19
- package/src/gantt/models/label-settings-model.d.ts +16 -16
- package/src/gantt/models/label-settings.js +19 -19
- package/src/gantt/models/resource-fields-model.d.ts +21 -21
- package/src/gantt/models/resource-fields.js +19 -19
- package/src/gantt/models/search-settings-model.d.ts +56 -56
- package/src/gantt/models/search-settings.js +19 -19
- package/src/gantt/models/selection-settings-model.d.ts +35 -35
- package/src/gantt/models/selection-settings.js +19 -19
- package/src/gantt/models/sort-settings-model.d.ts +24 -24
- package/src/gantt/models/sort-settings.js +19 -19
- package/src/gantt/models/splitter-settings-model.d.ts +30 -30
- package/src/gantt/models/splitter-settings.js +19 -19
- package/src/gantt/models/task-fields-model.d.ts +110 -110
- package/src/gantt/models/task-fields.js +19 -19
- package/src/gantt/models/timeline-settings-model.d.ts +71 -71
- package/src/gantt/models/timeline-settings.js +19 -19
- package/src/gantt/models/tooltip-settings-model.d.ts +26 -26
- package/src/gantt/models/tooltip-settings.js +19 -19
- package/src/gantt/renderer/chart-rows.js +49 -37
- package/src/gantt/renderer/connector-line.js +22 -18
- package/src/gantt/renderer/event-marker.js +1 -0
- package/src/gantt/renderer/nonworking-day.js +13 -6
- package/src/gantt/renderer/timeline.d.ts +1 -0
- package/src/gantt/renderer/timeline.js +51 -12
- package/src/gantt/renderer/tooltip.js +11 -3
- package/styles/bootstrap-dark.css +442 -427
- package/styles/bootstrap.css +442 -433
- package/styles/bootstrap4.css +454 -479
- package/styles/bootstrap5-dark.css +457 -433
- package/styles/bootstrap5.css +457 -433
- package/styles/fabric-dark.css +438 -421
- package/styles/fabric.css +445 -428
- package/styles/fluent-dark.css +1938 -0
- package/styles/fluent-dark.scss +1 -0
- package/styles/fluent.css +1938 -0
- package/styles/fluent.scss +1 -0
- package/styles/gantt/_all.scss +2 -2
- package/styles/gantt/_bootstrap-dark-definition.scss +210 -156
- package/styles/gantt/_bootstrap-definition.scss +211 -157
- package/styles/gantt/_bootstrap4-definition.scss +213 -158
- package/styles/gantt/_bootstrap5-definition.scss +215 -162
- package/styles/gantt/_fabric-dark-definition.scss +211 -157
- package/styles/gantt/_fabric-definition.scss +211 -157
- package/styles/gantt/_fluent-dark-definition.scss +1 -0
- package/styles/gantt/_fluent-definition.scss +215 -162
- package/styles/gantt/_fusionnew-definition.scss +214 -0
- package/styles/gantt/_highcontrast-definition.scss +211 -157
- package/styles/gantt/_highcontrast-light-definition.scss +211 -157
- package/styles/gantt/_layout.scss +1446 -1027
- package/styles/gantt/_material-dark-definition.scss +212 -157
- package/styles/gantt/_material-definition.scss +212 -157
- package/styles/gantt/_material3-definition.scss +215 -0
- package/styles/gantt/_tailwind-definition.scss +215 -161
- package/styles/gantt/_theme.scss +702 -668
- package/styles/gantt/bootstrap-dark.css +442 -427
- package/styles/gantt/bootstrap.css +442 -433
- package/styles/gantt/bootstrap4.css +454 -479
- package/styles/gantt/bootstrap5-dark.css +457 -433
- package/styles/gantt/bootstrap5.css +457 -433
- package/styles/gantt/fabric-dark.css +438 -421
- package/styles/gantt/fabric.css +445 -428
- package/styles/gantt/fluent-dark.css +1938 -0
- package/styles/gantt/fluent-dark.scss +22 -0
- package/styles/gantt/fluent.css +1938 -0
- package/styles/gantt/fluent.scss +22 -0
- package/styles/gantt/highcontrast-light.css +405 -405
- package/styles/gantt/highcontrast.css +444 -456
- package/styles/gantt/icons/_bootstrap-dark.scss +124 -113
- package/styles/gantt/icons/_bootstrap.scss +124 -113
- package/styles/gantt/icons/_bootstrap4.scss +124 -113
- package/styles/gantt/icons/_bootstrap5.scss +124 -112
- package/styles/gantt/icons/_fabric-dark.scss +124 -112
- package/styles/gantt/icons/_fabric.scss +124 -112
- package/styles/gantt/icons/_fluent-dark.scss +1 -0
- package/styles/gantt/icons/_fluent.scss +124 -112
- package/styles/gantt/icons/_fusionnew.scss +120 -0
- package/styles/gantt/icons/_highcontrast.scss +124 -112
- package/styles/gantt/icons/_material-dark.scss +124 -112
- package/styles/gantt/icons/_material.scss +124 -112
- package/styles/gantt/icons/_material3.scss +124 -0
- package/styles/gantt/icons/_tailwind-dark.scss +124 -113
- package/styles/gantt/icons/_tailwind.scss +124 -113
- package/styles/gantt/material-dark.css +446 -417
- package/styles/gantt/material.css +445 -419
- package/styles/gantt/tailwind-dark.css +452 -482
- package/styles/gantt/tailwind.css +449 -479
- package/styles/highcontrast-light.css +405 -405
- package/styles/highcontrast.css +444 -456
- package/styles/material-dark.css +446 -417
- package/styles/material.css +445 -419
- package/styles/tailwind-dark.css +452 -482
- package/styles/tailwind.css +449 -479
|
@@ -0,0 +1,282 @@
|
|
|
1
|
+
import { TimelineDetails } from './../base/interface';
|
|
2
|
+
import { PdfGanttTaskbarCollection } from './pdf-taskbar';
|
|
3
|
+
import { isNullOrUndefined } from '@syncfusion/ej2-base';
|
|
4
|
+
import { PageDetail } from '../base/interface';
|
|
5
|
+
import { PdfLayoutResult, PointF, PdfPage, PdfGraphics, SizeF, PdfPen, PdfColor } from '@syncfusion/ej2-pdf-export';
|
|
6
|
+
import { Gantt } from '../base/gantt';
|
|
7
|
+
import { PdfTreeGrid} from './pdf-treegrid';
|
|
8
|
+
import { PdfExportProperties } from '../base/interface';
|
|
9
|
+
import { PdfTimeline } from './pdf-timeline';
|
|
10
|
+
import { pixelToPoint, pointToPixel } from '../base/utils';
|
|
11
|
+
import { Timeline } from '../renderer/timeline';
|
|
12
|
+
import { PdfGanttPredecessor } from './pdf-connector-line';
|
|
13
|
+
import { TimelineViewMode } from '../base/enum';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
*
|
|
17
|
+
*/
|
|
18
|
+
export class PdfGantt extends PdfTreeGrid {
|
|
19
|
+
public taskbarCollection: PdfGanttTaskbarCollection[];
|
|
20
|
+
public predecessorCollection: PdfGanttPredecessor[];
|
|
21
|
+
private taskbars: PdfGanttTaskbarCollection;
|
|
22
|
+
private totalPages: number;
|
|
23
|
+
private exportProps: PdfExportProperties = {};
|
|
24
|
+
private perColumnPages: number;
|
|
25
|
+
private headerDetails: TimelineDetails[];
|
|
26
|
+
public pdfPageDetail: PageDetail[];
|
|
27
|
+
public result: PdfLayoutResult;
|
|
28
|
+
public timelineStartDate: Date;
|
|
29
|
+
private startPoint: PointF;
|
|
30
|
+
private startPageIndex: number;
|
|
31
|
+
public borderColor: PdfColor;
|
|
32
|
+
public predecessor: PdfGanttPredecessor;
|
|
33
|
+
public chartHeader: PdfTimeline;
|
|
34
|
+
public chartPageIndex: number;
|
|
35
|
+
public parent: Gantt;
|
|
36
|
+
|
|
37
|
+
constructor(parent: Gantt) {
|
|
38
|
+
super();
|
|
39
|
+
this.parent = parent;
|
|
40
|
+
this.chartHeader = new PdfTimeline(this);
|
|
41
|
+
this.predecessor = new PdfGanttPredecessor(parent, this);
|
|
42
|
+
this.headerDetails = [];
|
|
43
|
+
this.pdfPageDetail = [];
|
|
44
|
+
this.taskbarCollection = [];
|
|
45
|
+
this.predecessorCollection = [];
|
|
46
|
+
}
|
|
47
|
+
public get taskbar(): PdfGanttTaskbarCollection {
|
|
48
|
+
if (isNullOrUndefined(this.taskbars)) {
|
|
49
|
+
this.taskbars = new PdfGanttTaskbarCollection(this.parent);
|
|
50
|
+
}
|
|
51
|
+
return this.taskbars;
|
|
52
|
+
}
|
|
53
|
+
public drawChart(result: PdfLayoutResult): void {
|
|
54
|
+
this.result = result;
|
|
55
|
+
this.totalPages = this.result.page.section.count;
|
|
56
|
+
this.perColumnPages = this.totalPages / this.layouter.columnRanges.length;
|
|
57
|
+
this.calculateRange();
|
|
58
|
+
this.drawGantttChart();
|
|
59
|
+
this.drawPageBorder();
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
//Calcualte the header range for each pdf page based on schedule start and end date.
|
|
63
|
+
private calculateRange(): void {
|
|
64
|
+
const lastColumnRange: number[] = this.layouter.columnRanges[this.layouter.columnRanges.length - 1];
|
|
65
|
+
let totalColumnWidth: number = 0;
|
|
66
|
+
let isPageFinished: boolean = true;
|
|
67
|
+
let pageWidth: number = 0;
|
|
68
|
+
let remainWidth: number = 0;
|
|
69
|
+
let point: number = 0;
|
|
70
|
+
const headerWidth: number = pixelToPoint(this.chartHeader.width);
|
|
71
|
+
const timelineSettings: Timeline = this.parent.timelineModule;
|
|
72
|
+
|
|
73
|
+
for (let index: number = lastColumnRange[0]; index <= lastColumnRange[1]; index++) {
|
|
74
|
+
totalColumnWidth += this.layouter.treegrid.columns.getColumn(index).width;
|
|
75
|
+
}
|
|
76
|
+
totalColumnWidth += 0.5;
|
|
77
|
+
if (totalColumnWidth + 100 < this.result.page.getClientSize().width) {
|
|
78
|
+
remainWidth = this.result.page.getClientSize().width - totalColumnWidth;
|
|
79
|
+
this.chartPageIndex = this.startPageIndex = this.totalPages - this.perColumnPages;
|
|
80
|
+
isPageFinished = false;
|
|
81
|
+
this.startPoint = new PointF(totalColumnWidth, 0);
|
|
82
|
+
} else {
|
|
83
|
+
this.result.page.section.add();
|
|
84
|
+
this.chartPageIndex = this.startPageIndex = this.totalPages;
|
|
85
|
+
isPageFinished = true;
|
|
86
|
+
this.startPoint = new PointF(point, 0);
|
|
87
|
+
}
|
|
88
|
+
while (Math.round(point) < Math.round(headerWidth)) {
|
|
89
|
+
if (isPageFinished) {
|
|
90
|
+
pageWidth = this.result.page.getClientSize().width;
|
|
91
|
+
} else {
|
|
92
|
+
pageWidth = remainWidth;
|
|
93
|
+
isPageFinished = true;
|
|
94
|
+
}
|
|
95
|
+
const detail: TimelineDetails = {};
|
|
96
|
+
const range: number[] = [];
|
|
97
|
+
const convertedWidth: number = pixelToPoint(this.chartHeader.bottomTierCellWidth);
|
|
98
|
+
let width: number = 0;
|
|
99
|
+
if (this.chartHeader.bottomTierCellWidth !== 0) {
|
|
100
|
+
width = (Math.floor(pageWidth / convertedWidth) * convertedWidth);
|
|
101
|
+
}
|
|
102
|
+
range[0] = point;
|
|
103
|
+
if (headerWidth - point <= width) {
|
|
104
|
+
range[1] = headerWidth;
|
|
105
|
+
detail.totalWidth = pointToPixel(headerWidth - point);
|
|
106
|
+
} else {
|
|
107
|
+
range[1] = point + width;
|
|
108
|
+
detail.totalWidth = pointToPixel(width);
|
|
109
|
+
}
|
|
110
|
+
detail.startPoint = range[0];
|
|
111
|
+
detail.endPoint = range[1];
|
|
112
|
+
if (this.parent.cloneProjectStartDate.getHours() === 0 && this.parent.cloneProjectStartDate.getMinutes() === 0
|
|
113
|
+
&& this.parent.cloneProjectStartDate.getSeconds() === 0 ) {
|
|
114
|
+
this.parent.cloneProjectStartDate.setHours(8);
|
|
115
|
+
}
|
|
116
|
+
const timelineStartDate: Date = this.parent.dataOperation.getDateFromFormat(this.parent.cloneProjectStartDate);
|
|
117
|
+
const count: number = isNullOrUndefined(timelineSettings.customTimelineSettings.bottomTier.count) ?
|
|
118
|
+
timelineSettings.customTimelineSettings.topTier.count : timelineSettings.customTimelineSettings.bottomTier.count;
|
|
119
|
+
const scheduleType: TimelineViewMode = timelineSettings.customTimelineSettings.bottomTier.unit === 'None' ?
|
|
120
|
+
timelineSettings.customTimelineSettings.topTier.unit : timelineSettings.customTimelineSettings.bottomTier.unit;
|
|
121
|
+
switch (scheduleType) {
|
|
122
|
+
case 'Minutes':
|
|
123
|
+
{
|
|
124
|
+
detail.startDate = new Date(timelineStartDate.getTime());
|
|
125
|
+
const sDays: number = Math.floor(pointToPixel(detail.startPoint) / (this.chartHeader.bottomTierCellWidth));
|
|
126
|
+
detail.startDate.setMinutes(detail.startDate.getMinutes() + sDays * count);
|
|
127
|
+
detail.startDate.setSeconds(detail.startDate.getSeconds() + 1);
|
|
128
|
+
detail.endDate = new Date(detail.startDate.getTime());
|
|
129
|
+
const eDays: number = Math.floor(pointToPixel(detail.endPoint - detail.startPoint)
|
|
130
|
+
/ (this.chartHeader.bottomTierCellWidth));
|
|
131
|
+
detail.endDate.setMinutes(detail.endDate.getMinutes() + eDays * count);
|
|
132
|
+
break;
|
|
133
|
+
}
|
|
134
|
+
case 'Hour':
|
|
135
|
+
{
|
|
136
|
+
detail.startDate = new Date(timelineStartDate.getTime());
|
|
137
|
+
const sDays1: number = Math.floor(pointToPixel(detail.startPoint) / (this.chartHeader.bottomTierCellWidth));
|
|
138
|
+
detail.startDate.setHours(detail.startDate.getHours() + sDays1 * count);
|
|
139
|
+
detail.startDate.setMinutes(detail.startDate.getMinutes() + 1);
|
|
140
|
+
detail.endDate = new Date(detail.startDate.getTime());
|
|
141
|
+
const eDays1: number = Math.floor(pointToPixel(detail.endPoint - detail.startPoint)
|
|
142
|
+
/ (this.chartHeader.bottomTierCellWidth));
|
|
143
|
+
detail.endDate.setHours(detail.endDate.getHours() + eDays1 * count);
|
|
144
|
+
break;
|
|
145
|
+
}
|
|
146
|
+
case 'Day':
|
|
147
|
+
{
|
|
148
|
+
detail.startDate = new Date(timelineStartDate.getTime());
|
|
149
|
+
const startDays: number = (Math.round(detail.startPoint / pixelToPoint(this.chartHeader.bottomTierCellWidth)));
|
|
150
|
+
detail.startDate.setDate(detail.startDate.getDate() + startDays * count);
|
|
151
|
+
const endDays: number = Math.round(((detail.endPoint - detail.startPoint)
|
|
152
|
+
/ pixelToPoint(this.chartHeader.bottomTierCellWidth))) - 1;
|
|
153
|
+
detail.endDate = new Date(detail.startDate.getTime());
|
|
154
|
+
detail.endDate.setDate(detail.startDate.getDate() + endDays * count);
|
|
155
|
+
break;
|
|
156
|
+
}
|
|
157
|
+
case 'Week':
|
|
158
|
+
{
|
|
159
|
+
detail.startDate = new Date(timelineStartDate.getTime());
|
|
160
|
+
const startDays1: number = (detail.startPoint / pixelToPoint(this.chartHeader.bottomTierCellWidth) * 7);
|
|
161
|
+
detail.startDate.setDate(detail.startDate.getDate() + startDays1 * count);
|
|
162
|
+
const endDays1: number = Math.round((detail.endPoint - detail.startPoint)
|
|
163
|
+
/ pixelToPoint(this.chartHeader.bottomTierCellWidth)) * 7 - 1;
|
|
164
|
+
detail.endDate = new Date(detail.startDate.getTime());
|
|
165
|
+
detail.endDate.setDate(detail.startDate.getDate() + endDays1 * count);
|
|
166
|
+
break;
|
|
167
|
+
}
|
|
168
|
+
case 'Month':
|
|
169
|
+
{
|
|
170
|
+
detail.startDate = new Date(timelineStartDate.getTime());
|
|
171
|
+
const startDays2: number = (detail.startPoint / pixelToPoint(this.chartHeader.bottomTierCellWidth) * 31);
|
|
172
|
+
detail.startDate.setDate(detail.startDate.getDate() + startDays2 * count);
|
|
173
|
+
const endDays2: number = Math.round((detail.endPoint - detail.startPoint)
|
|
174
|
+
/ pixelToPoint(this.chartHeader.bottomTierCellWidth)) * 31 - 1;
|
|
175
|
+
detail.endDate = new Date(detail.startDate.getTime());
|
|
176
|
+
detail.endDate.setDate(detail.startDate.getDate() + endDays2 * count);
|
|
177
|
+
break;
|
|
178
|
+
}
|
|
179
|
+
case 'Year':
|
|
180
|
+
{
|
|
181
|
+
detail.startDate = new Date(timelineStartDate.getTime());
|
|
182
|
+
const startDays3: number = (detail.startPoint / pixelToPoint(this.chartHeader.bottomTierCellWidth) * 365);
|
|
183
|
+
detail.startDate.setDate(detail.startDate.getDate() + startDays3 * count);
|
|
184
|
+
const endDays3: number = Math.round((detail.endPoint - detail.startPoint)
|
|
185
|
+
/ pixelToPoint(this.chartHeader.bottomTierCellWidth)) * 365 - 1;
|
|
186
|
+
detail.endDate = new Date(detail.startDate.getTime());
|
|
187
|
+
detail.endDate.setDate(detail.startDate.getDate() + endDays3 * count);
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
this.headerDetails.push(detail);
|
|
192
|
+
point += width;
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
private drawPageBorder(): void {
|
|
197
|
+
const pages: PdfPage[] = this.result.page.section.getPages() as PdfPage[];
|
|
198
|
+
for (let index: number = 0; index < pages.length; index++) {
|
|
199
|
+
const page: PdfPage = pages[index];
|
|
200
|
+
const graphics: PdfGraphics = page.graphics;
|
|
201
|
+
const pageSize: SizeF = page.getClientSize();
|
|
202
|
+
const pen: PdfPen = new PdfPen(new PdfColor(206, 206, 206));
|
|
203
|
+
graphics.drawRectangle(pen, 0, 0, pageSize.width, pageSize.height);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
//Draw the gantt chart side
|
|
207
|
+
private drawGantttChart(): void {
|
|
208
|
+
let taskbarPoint: PointF = this.startPoint;
|
|
209
|
+
const pagePoint: PointF = new PointF();
|
|
210
|
+
let pageStartX: number = 0;
|
|
211
|
+
let cumulativeWidth: number = 0;
|
|
212
|
+
let cumulativeHeight: number = 0;
|
|
213
|
+
let totalHeight: number = 0;
|
|
214
|
+
let pageData: PageDetail;
|
|
215
|
+
this.headerDetails.forEach((detail: TimelineDetails, index: number): void => {
|
|
216
|
+
const page: PdfPage = this.result.page.section.getPages()[this.startPageIndex] as PdfPage;
|
|
217
|
+
this.chartHeader.drawTimeline(page, this.startPoint, detail);
|
|
218
|
+
taskbarPoint.y = taskbarPoint.y + pixelToPoint(this.parent.timelineModule.isSingleTier ? 45 : 60); // headerHeight
|
|
219
|
+
pageStartX = taskbarPoint.x;
|
|
220
|
+
cumulativeHeight = pixelToPoint(this.parent.timelineModule.isSingleTier ? 45 : 60); // headerHeight
|
|
221
|
+
this.headerDetails[this.headerDetails.indexOf(detail)].startIndex = this.startPageIndex;
|
|
222
|
+
this.headerDetails[this.headerDetails.indexOf(detail)].pageStartPoint = taskbarPoint;
|
|
223
|
+
for (let i: number = 0; i < this.taskbarCollection.length; i++) {
|
|
224
|
+
const task: PdfGanttTaskbarCollection = this.taskbarCollection[i];
|
|
225
|
+
const rowHeight: number = this.rows.getRow(i + 1).height;
|
|
226
|
+
const pdfPage: PdfPage = this.result.page.section.getPages()[this.startPageIndex] as PdfPage;
|
|
227
|
+
/* eslint-disable-next-line */
|
|
228
|
+
const isNextPage: boolean = task.drawTaskbar(pdfPage, taskbarPoint, detail, cumulativeWidth, rowHeight, this.taskbarCollection[i]);
|
|
229
|
+
if (isNextPage) {
|
|
230
|
+
if (this.enableHeader) {
|
|
231
|
+
taskbarPoint.y = pixelToPoint(this.parent.timelineModule.isSingleTier ? 45 : 60);
|
|
232
|
+
} else {
|
|
233
|
+
taskbarPoint.y = 0;
|
|
234
|
+
}
|
|
235
|
+
this.startPageIndex++;
|
|
236
|
+
pageData = {};
|
|
237
|
+
pageData.height = cumulativeHeight;
|
|
238
|
+
pageData.pageStartX = pageStartX;
|
|
239
|
+
pageData.startPoint = { ...pagePoint };
|
|
240
|
+
pageData.width = pixelToPoint(detail.totalWidth);
|
|
241
|
+
this.pdfPageDetail.push(pageData);
|
|
242
|
+
pagePoint.y += pageData.height;
|
|
243
|
+
if (this.enableHeader) {
|
|
244
|
+
cumulativeHeight = this.chartHeader.height;
|
|
245
|
+
} else {
|
|
246
|
+
taskbarPoint.y = 0;
|
|
247
|
+
cumulativeHeight = 0;
|
|
248
|
+
}
|
|
249
|
+
}
|
|
250
|
+
taskbarPoint.y += rowHeight;
|
|
251
|
+
cumulativeHeight += rowHeight;
|
|
252
|
+
// eslint-disable-next-line
|
|
253
|
+
totalHeight += rowHeight;
|
|
254
|
+
}
|
|
255
|
+
this.headerDetails[index].endIndex = this.startPageIndex;
|
|
256
|
+
cumulativeWidth += detail.totalWidth;
|
|
257
|
+
pageData = {};
|
|
258
|
+
pageData.height = cumulativeHeight;
|
|
259
|
+
pageData.pageStartX = pageStartX;
|
|
260
|
+
pageData.startPoint = { ...pagePoint };
|
|
261
|
+
pageData.width = pixelToPoint(detail.totalWidth);
|
|
262
|
+
this.pdfPageDetail.push(pageData);
|
|
263
|
+
pagePoint.x += pageData.width;
|
|
264
|
+
pagePoint.y = 0;
|
|
265
|
+
if (this.enableHeader) {
|
|
266
|
+
cumulativeHeight = this.chartHeader.height;
|
|
267
|
+
} else {
|
|
268
|
+
taskbarPoint.y = 0;
|
|
269
|
+
}
|
|
270
|
+
if (this.headerDetails.indexOf(detail) !== this.headerDetails.length - 1) {
|
|
271
|
+
this.result.page.section.add();
|
|
272
|
+
this.startPageIndex = this.result.page.section.count - 1;
|
|
273
|
+
taskbarPoint = this.startPoint = new PointF(0, 0);
|
|
274
|
+
}
|
|
275
|
+
});
|
|
276
|
+
// Draw predecessor line.
|
|
277
|
+
for (let i: number = 0; i < this.predecessorCollection.length; i++) {
|
|
278
|
+
const predecessor: PdfGanttPredecessor = this.predecessorCollection[i];
|
|
279
|
+
predecessor.drawPredecessor(this);
|
|
280
|
+
}
|
|
281
|
+
}
|
|
282
|
+
}
|
|
@@ -0,0 +1,395 @@
|
|
|
1
|
+
import {
|
|
2
|
+
PointF, PdfColor, PdfStringLayouter, PdfStringLayoutResult, PdfPage, PdfSection, PdfGraphics, PdfPen, PdfBrush, PdfSolidBrush,
|
|
3
|
+
RectangleF, SizeF, PdfFont, PdfStandardFont, PdfFontStyle, PdfFontFamily, PdfStringFormat, PdfVerticalAlignment,
|
|
4
|
+
PdfTextAlignment, PdfWordWrapType
|
|
5
|
+
} from '@syncfusion/ej2-pdf-export';
|
|
6
|
+
import { TimelineDetails, TaskLabel } from './../base/interface';
|
|
7
|
+
import { Gantt } from '../base/gantt';
|
|
8
|
+
import { pixelToPoint } from '../base/utils';
|
|
9
|
+
import { isNullOrUndefined } from '@syncfusion/ej2-base';
|
|
10
|
+
|
|
11
|
+
/**
|
|
12
|
+
* @hidden
|
|
13
|
+
*/
|
|
14
|
+
export class PdfGanttTaskbarCollection {
|
|
15
|
+
public endDate?: Date;
|
|
16
|
+
/** Defines the duration of task. */
|
|
17
|
+
public duration?: number;
|
|
18
|
+
/** Defines the duration unit of task. */
|
|
19
|
+
public durationUnit?: string;
|
|
20
|
+
/** Defines the task is auto schedule-able or not. */
|
|
21
|
+
public isAutoSchedule?: boolean;
|
|
22
|
+
/** Defines the task is milestone or not. */
|
|
23
|
+
public isMilestone?: boolean;
|
|
24
|
+
/** Defines the left of task.
|
|
25
|
+
*
|
|
26
|
+
* @hidden
|
|
27
|
+
*/
|
|
28
|
+
public left?: number;
|
|
29
|
+
/** Defines the progress of task. */
|
|
30
|
+
public progress?: number;
|
|
31
|
+
/** Defines the progress width of task. */
|
|
32
|
+
public progressWidth?: number;
|
|
33
|
+
/** Defines the start date of task. */
|
|
34
|
+
public startDate?: Date;
|
|
35
|
+
/** Defines the id of task. */
|
|
36
|
+
public taskId?: string;
|
|
37
|
+
/** Defines the parent id of task. */
|
|
38
|
+
public parentId?: string;
|
|
39
|
+
/** Defines the name of task. */
|
|
40
|
+
public taskName?: string;
|
|
41
|
+
/** Defines the width of task. */
|
|
42
|
+
public width?: number;
|
|
43
|
+
/** Defines the unique id of task. */
|
|
44
|
+
public uniqueID?: string;
|
|
45
|
+
/** Defines the total progress of task. */
|
|
46
|
+
public totalProgress?: number;
|
|
47
|
+
/** Defines the total duration of task. */
|
|
48
|
+
public totalDuration?: number;
|
|
49
|
+
/**
|
|
50
|
+
* @private
|
|
51
|
+
*/
|
|
52
|
+
public unscheduledTaskBy?: string;
|
|
53
|
+
/**
|
|
54
|
+
* @private
|
|
55
|
+
*/
|
|
56
|
+
public unscheduleStarteDate?: Date;
|
|
57
|
+
/**
|
|
58
|
+
* @private
|
|
59
|
+
*/
|
|
60
|
+
public unscheduleEndDate?: Date;
|
|
61
|
+
public isParentTask?: boolean;
|
|
62
|
+
public isScheduledTask?: boolean;
|
|
63
|
+
public height: number;
|
|
64
|
+
public fontFamily: PdfFontFamily;
|
|
65
|
+
public gridLineColor: PdfColor;
|
|
66
|
+
public progressFontColor: PdfColor;
|
|
67
|
+
public taskColor: PdfColor;
|
|
68
|
+
public labelColor: PdfColor;
|
|
69
|
+
public taskBorderColor: PdfColor;
|
|
70
|
+
public progressColor: PdfColor;
|
|
71
|
+
public milestoneColor: PdfColor;
|
|
72
|
+
public taskbar: PdfGanttTaskbarCollection[];
|
|
73
|
+
public parent: Gantt;
|
|
74
|
+
public isCompleted: boolean;
|
|
75
|
+
/**
|
|
76
|
+
* @private
|
|
77
|
+
*/
|
|
78
|
+
public leftTaskLabel: TaskLabel = {};
|
|
79
|
+
/**
|
|
80
|
+
* @private
|
|
81
|
+
*/
|
|
82
|
+
public rightTaskLabel: TaskLabel = {};
|
|
83
|
+
public startPage: number = -1;
|
|
84
|
+
public endPage: number = -1;
|
|
85
|
+
public isStartPoint: boolean;
|
|
86
|
+
public taskStartPoint: PointF;
|
|
87
|
+
public add(): PdfGanttTaskbarCollection {
|
|
88
|
+
return new PdfGanttTaskbarCollection(this.parent);
|
|
89
|
+
}
|
|
90
|
+
constructor(parent?: Gantt) {
|
|
91
|
+
this.parent = parent;
|
|
92
|
+
}
|
|
93
|
+
/**
|
|
94
|
+
* @param {PdfPage} page .
|
|
95
|
+
* @returns {PdfPage} .
|
|
96
|
+
* Get the next PDF page
|
|
97
|
+
*/
|
|
98
|
+
private GetNextPage(page: PdfPage): PdfPage {
|
|
99
|
+
const section: PdfSection = page.section;
|
|
100
|
+
const index: number = section.indexOf(page);
|
|
101
|
+
let nextPage: PdfPage = null;
|
|
102
|
+
if (index === section.count - 1) {
|
|
103
|
+
nextPage = (section.add() as PdfPage);
|
|
104
|
+
} else {
|
|
105
|
+
nextPage = (section.getPages()[index + 1] as PdfPage);
|
|
106
|
+
}
|
|
107
|
+
return nextPage;
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Draw the taskbar, chart back ground
|
|
111
|
+
*
|
|
112
|
+
* @private
|
|
113
|
+
*/
|
|
114
|
+
/* eslint-disable */
|
|
115
|
+
public drawTaskbar(page: PdfPage, startPoint: PointF, detail: TimelineDetails, cumulativeWidth: number, rowHeight: number, taskbar: PdfGanttTaskbarCollection): boolean {
|
|
116
|
+
let taskGraphics: PdfGraphics = page.graphics;
|
|
117
|
+
let isNextPage: boolean = false;
|
|
118
|
+
const pageSize: SizeF = page.getClientSize();
|
|
119
|
+
const yPoint: number = startPoint.y + rowHeight;
|
|
120
|
+
//code for while current pdf page is exceed
|
|
121
|
+
if (yPoint > pageSize.height) {
|
|
122
|
+
page = this.GetNextPage(page);
|
|
123
|
+
taskGraphics = page.graphics;
|
|
124
|
+
startPoint.y = 0;
|
|
125
|
+
if (this.parent.pdfExportModule.gantt.enableHeader) {
|
|
126
|
+
this.parent.pdfExportModule.gantt.chartHeader.drawPageTimeline(page, startPoint, detail);
|
|
127
|
+
startPoint.y = pixelToPoint(this.parent.timelineModule.isSingleTier ? 45 : 60);
|
|
128
|
+
}
|
|
129
|
+
isNextPage = true;
|
|
130
|
+
}
|
|
131
|
+
this.drawLeftLabel(page, startPoint, detail, cumulativeWidth);
|
|
132
|
+
//Draw Taskbar
|
|
133
|
+
const font: PdfFont = new PdfStandardFont(this.fontFamily, 9, PdfFontStyle.Regular);
|
|
134
|
+
const fontColor: PdfPen = null;
|
|
135
|
+
const fontBrush: PdfBrush = new PdfSolidBrush(this.progressFontColor);
|
|
136
|
+
const progressFormat: PdfStringFormat = new PdfStringFormat();
|
|
137
|
+
progressFormat.lineAlignment = PdfVerticalAlignment.Middle;
|
|
138
|
+
progressFormat.alignment = PdfTextAlignment.Right;
|
|
139
|
+
let pageIndex: number = -1;
|
|
140
|
+
if (!taskbar.isMilestone) {
|
|
141
|
+
const taskbarPen: PdfPen = new PdfPen(taskbar.taskBorderColor);
|
|
142
|
+
const taskBrush: PdfBrush = new PdfSolidBrush(taskbar.taskColor);
|
|
143
|
+
const progressPen: PdfPen = new PdfPen(taskbar.progressColor);
|
|
144
|
+
const progressBrush: PdfBrush = new PdfSolidBrush(taskbar.progressColor);
|
|
145
|
+
const adjustHeight: number = pixelToPoint((this.parent.rowHeight - this.height) / 2.0);
|
|
146
|
+
pageIndex = page.section.indexOf(page);
|
|
147
|
+
const startDate: Date = isNullOrUndefined(this.unscheduleStarteDate) ? this.startDate : this.unscheduleStarteDate;
|
|
148
|
+
const endDate: Date = isNullOrUndefined(this.unscheduleEndDate) ? this.endDate : this.unscheduleEndDate;
|
|
149
|
+
//Task start and end date both are in the range of header split up start and end date
|
|
150
|
+
if (detail.startDate <= startDate && endDate <= detail.endDate) {
|
|
151
|
+
if (!this.isStartPoint) {
|
|
152
|
+
this.taskStartPoint = { ...startPoint };
|
|
153
|
+
this.isStartPoint = true;
|
|
154
|
+
}
|
|
155
|
+
if (!this.isScheduledTask && this.unscheduledTaskBy !== 'duration') {
|
|
156
|
+
this.drawUnscheduledTask(taskGraphics, startPoint, cumulativeWidth, adjustHeight);
|
|
157
|
+
} else {
|
|
158
|
+
taskGraphics.drawRectangle(taskbarPen, taskBrush, startPoint.x + pixelToPoint(this.left - cumulativeWidth) + 0.5, startPoint.y + adjustHeight, pixelToPoint(taskbar.width), pixelToPoint(taskbar.height));
|
|
159
|
+
if (this.progress > 0 && this.progressWidth > 0 && this.isScheduledTask) {
|
|
160
|
+
taskGraphics.drawRectangle(progressPen, progressBrush, startPoint.x + pixelToPoint(this.left - cumulativeWidth) + 0.5, startPoint.y + adjustHeight, pixelToPoint(taskbar.progressWidth), pixelToPoint(taskbar.height));
|
|
161
|
+
if (!isNullOrUndefined(this.parent.taskFields.progress) && !isNullOrUndefined(this.parent.labelSettings.taskLabel)) {
|
|
162
|
+
taskGraphics.drawString(this.progress.toString(), font, fontColor, fontBrush, startPoint.x + pixelToPoint(this.left - cumulativeWidth), startPoint.y + adjustHeight, pixelToPoint(this.progressWidth), pixelToPoint(this.height), progressFormat);
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
this.isCompleted = true;
|
|
167
|
+
this.startPage = pageIndex;
|
|
168
|
+
this.endPage = pageIndex;
|
|
169
|
+
}
|
|
170
|
+
//Task start date is in the range of header split up start and end date
|
|
171
|
+
else if (detail.startDate <= startDate && detail.endDate >= startDate && (endDate >= detail.endDate)) {
|
|
172
|
+
if (!this.isStartPoint) {
|
|
173
|
+
this.taskStartPoint = { ...startPoint };
|
|
174
|
+
this.isStartPoint = true;
|
|
175
|
+
}
|
|
176
|
+
let renderWidth: number = 0;
|
|
177
|
+
this.width = this.width - (detail.totalWidth - (this.left - cumulativeWidth));
|
|
178
|
+
renderWidth = (detail.totalWidth - (this.left - cumulativeWidth));
|
|
179
|
+
if (!this.isScheduledTask && this.unscheduledTaskBy !== 'duration') {
|
|
180
|
+
this.drawUnscheduledTask(taskGraphics, startPoint, cumulativeWidth, adjustHeight);
|
|
181
|
+
} else {
|
|
182
|
+
taskGraphics.drawRectangle(taskbarPen, taskBrush, startPoint.x + pixelToPoint(this.left - cumulativeWidth) + 0.5, startPoint.y + adjustHeight, pixelToPoint(renderWidth), pixelToPoint(taskbar.height));
|
|
183
|
+
if (this.progress > 0 && this.progressWidth > 0 && this.isScheduledTask) {
|
|
184
|
+
let progressBoundsWidth: number = 0;
|
|
185
|
+
if (this.progressWidth <= renderWidth) {
|
|
186
|
+
progressBoundsWidth = this.progressWidth;
|
|
187
|
+
} else {
|
|
188
|
+
progressBoundsWidth = renderWidth;
|
|
189
|
+
}
|
|
190
|
+
taskGraphics.drawRectangle(progressPen, progressBrush, startPoint.x + pixelToPoint(this.left - cumulativeWidth) + 0.5, startPoint.y + adjustHeight, pixelToPoint(progressBoundsWidth), pixelToPoint(taskbar.height));
|
|
191
|
+
this.progressWidth -= progressBoundsWidth;
|
|
192
|
+
if (this.progressWidth === 0 && this.progress !== 0 && this.parent.labelSettings.taskLabel) {
|
|
193
|
+
taskGraphics.drawString(this.progress.toString(), font, fontColor, fontBrush, startPoint.x + pixelToPoint(this.left - cumulativeWidth), (startPoint.y + adjustHeight), pixelToPoint(progressBoundsWidth), pixelToPoint(this.height), progressFormat);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
}
|
|
197
|
+
this.left = 0;
|
|
198
|
+
this.isCompleted = false;
|
|
199
|
+
this.startPage = pageIndex;
|
|
200
|
+
}
|
|
201
|
+
//Task end date is in the range of header split up start and end date
|
|
202
|
+
else if (endDate <= detail.endDate && detail.startDate <= endDate && !this.isCompleted) {
|
|
203
|
+
if (!this.isStartPoint) {
|
|
204
|
+
this.taskStartPoint = { ...startPoint };
|
|
205
|
+
this.isStartPoint = true;
|
|
206
|
+
}
|
|
207
|
+
taskGraphics.drawRectangle(taskbarPen, taskBrush, startPoint.x + pixelToPoint(taskbar.left + 0.5), startPoint.y + adjustHeight, pixelToPoint(taskbar.width), pixelToPoint(taskbar.height));
|
|
208
|
+
if (this.isScheduledTask) {
|
|
209
|
+
taskGraphics.drawRectangle(progressPen, progressBrush, startPoint.x + pixelToPoint(taskbar.left + 0.5), startPoint.y + adjustHeight, pixelToPoint(taskbar.progressWidth), pixelToPoint(taskbar.height));
|
|
210
|
+
if (this.progressWidth === 0 && this.progress !== 0) {
|
|
211
|
+
taskGraphics.drawString(this.progress.toString(), font, fontColor, fontBrush, startPoint.x + pixelToPoint(this.left), (startPoint.y + adjustHeight), pixelToPoint(this.progressWidth), pixelToPoint(this.height), progressFormat);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
this.isCompleted = true;
|
|
215
|
+
this.endPage = pageIndex;
|
|
216
|
+
}
|
|
217
|
+
//Header splitup start and end date with in the task start and end date.
|
|
218
|
+
//So the task is takes entire width of page.
|
|
219
|
+
else if (startDate < detail.startDate && endDate > detail.endDate) {
|
|
220
|
+
if (!this.isStartPoint) {
|
|
221
|
+
this.taskStartPoint = { ...startPoint };
|
|
222
|
+
this.isStartPoint = true;
|
|
223
|
+
}
|
|
224
|
+
taskGraphics.drawRectangle(taskbarPen, taskBrush, startPoint.x + pixelToPoint(taskbar.left) + 0.5, startPoint.y + adjustHeight, pixelToPoint(detail.totalWidth), pixelToPoint(taskbar.height));
|
|
225
|
+
if (this.progress > 0 && this.progressWidth > 0 && this.isScheduledTask) {
|
|
226
|
+
let progressBoundsWidth: number = 0;
|
|
227
|
+
if (this.progressWidth <= detail.totalWidth) {
|
|
228
|
+
progressBoundsWidth = this.progressWidth;
|
|
229
|
+
} else {
|
|
230
|
+
progressBoundsWidth = detail.totalWidth;
|
|
231
|
+
}
|
|
232
|
+
taskGraphics.drawRectangle(progressPen, progressBrush, startPoint.x + pixelToPoint(taskbar.left) + 0.5, startPoint.y + adjustHeight, pixelToPoint(progressBoundsWidth), pixelToPoint(taskbar.height));
|
|
233
|
+
this.progressWidth -= progressBoundsWidth;
|
|
234
|
+
if (this.progressWidth === 0 && this.progress !== 0) {
|
|
235
|
+
taskGraphics.drawString(this.progress.toString(), font, fontColor, fontBrush, startPoint.x + pixelToPoint(this.left), (startPoint.y + adjustHeight), pixelToPoint(progressBoundsWidth), pixelToPoint(this.height), progressFormat);
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
this.isCompleted = false;
|
|
239
|
+
this.width -= detail.totalWidth;
|
|
240
|
+
}
|
|
241
|
+
} else {
|
|
242
|
+
this.drawMilestone(page, startPoint, detail, cumulativeWidth);
|
|
243
|
+
}
|
|
244
|
+
this.drawRightLabel(page, startPoint, detail, cumulativeWidth);
|
|
245
|
+
return isNextPage;
|
|
246
|
+
}
|
|
247
|
+
/* eslint-enable */
|
|
248
|
+
/**
|
|
249
|
+
* @param {PdfPage} page .
|
|
250
|
+
* @param {PointF} startPoint .
|
|
251
|
+
* @param {TimelineDetails} detail .
|
|
252
|
+
* @param {number} cumulativeWidth .
|
|
253
|
+
* @returns {void}
|
|
254
|
+
* Draw task right side label
|
|
255
|
+
*/
|
|
256
|
+
private drawRightLabel(page: PdfPage, startPoint: PointF, detail: TimelineDetails, cumulativeWidth: number): void {
|
|
257
|
+
let left: number;
|
|
258
|
+
const graphics: PdfGraphics = page.graphics;
|
|
259
|
+
if (this.rightTaskLabel.isLeftCalculated) {
|
|
260
|
+
left = this.rightTaskLabel.left;
|
|
261
|
+
} else {
|
|
262
|
+
left = pixelToPoint(this.rightTaskLabel.left);
|
|
263
|
+
}
|
|
264
|
+
const actualLeft: number = left - pixelToPoint(cumulativeWidth) + startPoint.x;
|
|
265
|
+
if (detail.startPoint <= left && left < detail.endPoint &&
|
|
266
|
+
!isNullOrUndefined(this.rightTaskLabel.value) && !this.rightTaskLabel.isCompleted) {
|
|
267
|
+
const result: PdfStringLayoutResult = this.getWidth(this.rightTaskLabel.value, detail.endPoint - left, 15);
|
|
268
|
+
const font: PdfFont = new PdfStandardFont(this.fontFamily, 9);
|
|
269
|
+
const adjustHeight: number = (pixelToPoint(this.parent.rowHeight) - result.actualSize.height) / 2;
|
|
270
|
+
const point: PointF = new PointF(actualLeft, startPoint.y + adjustHeight);
|
|
271
|
+
const size: SizeF = new SizeF(result.actualSize.width, result.actualSize.height);
|
|
272
|
+
const labelBounds: RectangleF = new RectangleF(point, size);
|
|
273
|
+
const labelFormat: PdfStringFormat = new PdfStringFormat();
|
|
274
|
+
labelFormat.alignment = PdfTextAlignment.Right;
|
|
275
|
+
labelFormat.lineAlignment = PdfVerticalAlignment.Middle;
|
|
276
|
+
if (result.actualSize.width > 0) {
|
|
277
|
+
const fontColor: PdfPen = null;
|
|
278
|
+
const fontBrush: PdfBrush = new PdfSolidBrush(this.labelColor);
|
|
279
|
+
/* eslint-disable-next-line */
|
|
280
|
+
graphics.drawString(result.lines[0].text, font, fontColor, fontBrush, labelBounds.x, labelBounds.y, result.actualSize.width, result.actualSize.height, labelFormat);
|
|
281
|
+
if (result.remainder !== null) {
|
|
282
|
+
this.rightTaskLabel.value = result.remainder;
|
|
283
|
+
this.rightTaskLabel.left = detail.endPoint;
|
|
284
|
+
this.rightTaskLabel.isLeftCalculated = true;
|
|
285
|
+
} else {
|
|
286
|
+
this.rightTaskLabel.isCompleted = true;
|
|
287
|
+
}
|
|
288
|
+
} else {
|
|
289
|
+
this.rightTaskLabel.left = detail.endPoint;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
/**
|
|
294
|
+
* @param {PdfPage} page .
|
|
295
|
+
* @param {PointF} startPoint .
|
|
296
|
+
* @param {TimelineDetails} detail .
|
|
297
|
+
* @param {number} cumulativeWidth .
|
|
298
|
+
* @returns {void}
|
|
299
|
+
* Draw task left task label
|
|
300
|
+
*/
|
|
301
|
+
private drawLeftLabel(page: PdfPage, startPoint: PointF, detail: TimelineDetails, cumulativeWidth: number): void {
|
|
302
|
+
const graphics: PdfGraphics = page.graphics;
|
|
303
|
+
let left: number;
|
|
304
|
+
if (!isNullOrUndefined(this.leftTaskLabel.value)) {
|
|
305
|
+
let labelLeft: number = 0;
|
|
306
|
+
labelLeft = this.left;
|
|
307
|
+
if (!this.leftTaskLabel.isLeftCalculated) {
|
|
308
|
+
const result: PdfStringLayoutResult = this.getWidth(this.leftTaskLabel.value, Number.MAX_VALUE, 15);
|
|
309
|
+
const reduceLeft: number = this.isMilestone ? Math.floor(this.parent.chartRowsModule.taskBarHeight / 2) + 33 : 33; // 33 indicates default timeline cell width
|
|
310
|
+
left = pixelToPoint(labelLeft - reduceLeft) - result.actualSize.width;
|
|
311
|
+
this.leftTaskLabel.left = left;
|
|
312
|
+
this.leftTaskLabel.isLeftCalculated = true;
|
|
313
|
+
} else {
|
|
314
|
+
left = this.leftTaskLabel.left;
|
|
315
|
+
}
|
|
316
|
+
const actualLeft: number = left - pixelToPoint(cumulativeWidth) + startPoint.x;
|
|
317
|
+
if (detail.startPoint <= left && left < detail.endPoint && !isNullOrUndefined(this.leftTaskLabel.value)
|
|
318
|
+
&& !this.leftTaskLabel.isCompleted) {
|
|
319
|
+
const result: PdfStringLayoutResult = this.getWidth(this.leftTaskLabel.value, detail.endPoint - left, 15);
|
|
320
|
+
const font: PdfFont = new PdfStandardFont(this.fontFamily, 9);
|
|
321
|
+
const adjustHeight: number = (pixelToPoint(this.parent.rowHeight) - result.actualSize.height) / 2;
|
|
322
|
+
const rightLabelpoint: PointF = new PointF(actualLeft, startPoint.y + adjustHeight);
|
|
323
|
+
const rightLabelSize: SizeF = new SizeF(result.actualSize.width, result.actualSize.height);
|
|
324
|
+
const rightLabelBounds: RectangleF = new RectangleF(rightLabelpoint, rightLabelSize);
|
|
325
|
+
const rightLabelFormat: PdfStringFormat = new PdfStringFormat();
|
|
326
|
+
rightLabelFormat.alignment = PdfTextAlignment.Right;
|
|
327
|
+
rightLabelFormat.lineAlignment = PdfVerticalAlignment.Middle;
|
|
328
|
+
if (result.actualSize.width > 0) {
|
|
329
|
+
const fontColor: PdfPen = null;
|
|
330
|
+
const fontBrush: PdfBrush = new PdfSolidBrush(this.labelColor);
|
|
331
|
+
/* eslint-disable-next-line */
|
|
332
|
+
graphics.drawString(result.lines[0].text, font, fontColor, fontBrush, rightLabelBounds.x, rightLabelBounds.y, result.actualSize.width, result.actualSize.height, rightLabelFormat);
|
|
333
|
+
if (result.remainder !== null) {
|
|
334
|
+
this.leftTaskLabel.value = result.remainder;
|
|
335
|
+
this.leftTaskLabel.left = detail.endPoint;
|
|
336
|
+
} else {
|
|
337
|
+
this.leftTaskLabel.isCompleted = true;
|
|
338
|
+
}
|
|
339
|
+
} else {
|
|
340
|
+
this.leftTaskLabel.left = detail.endPoint;
|
|
341
|
+
}
|
|
342
|
+
}
|
|
343
|
+
}
|
|
344
|
+
}
|
|
345
|
+
private getWidth(value: string, width: number, height: number): PdfStringLayoutResult {
|
|
346
|
+
const font: PdfFont = new PdfStandardFont(this.fontFamily, 9);
|
|
347
|
+
const layouter: PdfStringLayouter = new PdfStringLayouter();
|
|
348
|
+
const progressFormat: PdfStringFormat = new PdfStringFormat();
|
|
349
|
+
progressFormat.alignment = PdfTextAlignment.Left;
|
|
350
|
+
progressFormat.wordWrap = PdfWordWrapType.Character;
|
|
351
|
+
progressFormat.lineAlignment = PdfVerticalAlignment.Middle;
|
|
352
|
+
/* eslint-disable-next-line */
|
|
353
|
+
const result: PdfStringLayoutResult = layouter.layout(value, font, progressFormat, new SizeF(width, height), false, new SizeF(width, height));
|
|
354
|
+
return result;
|
|
355
|
+
}
|
|
356
|
+
/**
|
|
357
|
+
* @param {PdfGraphics} taskGraphics .
|
|
358
|
+
* @param {PointF} startPoint .
|
|
359
|
+
* @param {number} cumulativeWidth .
|
|
360
|
+
* @param {number} adjustHeight .
|
|
361
|
+
* @returns {void}
|
|
362
|
+
* Draw Unscheduled Task
|
|
363
|
+
*/
|
|
364
|
+
private drawUnscheduledTask(taskGraphics: PdfGraphics, startPoint: PointF, cumulativeWidth: number, adjustHeight: number): void {
|
|
365
|
+
const taskBrush: PdfBrush = new PdfSolidBrush(this.taskColor);
|
|
366
|
+
/* eslint-disable-next-line */
|
|
367
|
+
taskGraphics.drawRectangle(taskBrush, startPoint.x + pixelToPoint(this.left - cumulativeWidth), startPoint.y + adjustHeight, pixelToPoint(3), pixelToPoint(this.height));
|
|
368
|
+
}
|
|
369
|
+
/**
|
|
370
|
+
* @param {PdfPage} page .
|
|
371
|
+
* @param {PointF} startPoint .
|
|
372
|
+
* @param {TimelineDetails} detail .
|
|
373
|
+
* @param {number} cumulativeWidth .
|
|
374
|
+
* @returns {void}
|
|
375
|
+
* Draw milestone task
|
|
376
|
+
*/
|
|
377
|
+
private drawMilestone(page: PdfPage, startPoint: PointF, detail: TimelineDetails, cumulativeWidth: number): void {
|
|
378
|
+
if (detail.startDate <= this.startDate && this.startDate <= detail.endDate) {
|
|
379
|
+
const taskGraphics: PdfGraphics = page.graphics;
|
|
380
|
+
const pageIndex: number = page.section.indexOf(page);
|
|
381
|
+
this.taskStartPoint = { ...startPoint };
|
|
382
|
+
const milestonePen: PdfPen = new PdfPen(this.milestoneColor);
|
|
383
|
+
const adjustHeight: number = pixelToPoint(((this.parent.rowHeight - this.height) / 2.0));
|
|
384
|
+
const milestoneBrush: PdfBrush = new PdfSolidBrush(this.milestoneColor);
|
|
385
|
+
taskGraphics.save(); //saving graphics state
|
|
386
|
+
const height: number = Math.floor(this.parent.chartRowsModule.taskBarHeight * 0.6);
|
|
387
|
+
/* eslint-disable-next-line */
|
|
388
|
+
taskGraphics.translateTransform(startPoint.x + pixelToPoint(this.left - cumulativeWidth), startPoint.y + adjustHeight - (this.parent.chartRowsModule.taskBarHeight * 0.7) / 2);
|
|
389
|
+
taskGraphics.rotateTransform(45); //apply rotation
|
|
390
|
+
taskGraphics.drawRectangle(milestonePen, milestoneBrush, 0, 0, pixelToPoint(height), pixelToPoint(height));
|
|
391
|
+
taskGraphics.restore(); //restoring graphics state
|
|
392
|
+
this.endPage = this.startPage = pageIndex;
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|