@worktile/gantt 12.1.3 → 12.2.0

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.
@@ -2,7 +2,7 @@ import * as i0 from '@angular/core';
2
2
  import { InjectionToken, EventEmitter, Directive, Inject, Input, Output, ContentChild, HostBinding, Component, Pipe, ViewChild, Injectable, Optional, forwardRef, ChangeDetectionStrategy, ContentChildren, NgModule } from '@angular/core';
3
3
  import * as i2 from '@angular/common';
4
4
  import { CommonModule } from '@angular/common';
5
- import { take, skip, takeUntil, startWith, map, pairwise, auditTime, finalize } from 'rxjs/operators';
5
+ import { take, skip, takeUntil, startWith, map, pairwise, auditTime, debounceTime, finalize } from 'rxjs/operators';
6
6
  import { BehaviorSubject, Subject, merge, fromEvent } from 'rxjs';
7
7
  import { fromUnixTime, getWeek, getDaysInMonth, differenceInCalendarDays, setDate, addSeconds, addMinutes, addHours, addDays, addWeeks, addMonths, addQuarters, addYears, startOfDay, startOfWeek, startOfMonth, startOfQuarter, startOfYear, endOfDay, endOfWeek, endOfMonth, endOfQuarter, endOfYear, getUnixTime, format, isWeekend, isToday, differenceInDays, differenceInCalendarQuarters, eachMonthOfInterval, eachYearOfInterval, eachWeekOfInterval, eachDayOfInterval, differenceInCalendarYears } from 'date-fns';
8
8
  export { addDays, addHours, addMinutes, addMonths, addQuarters, addSeconds, addWeeks, addYears, differenceInCalendarDays, differenceInCalendarQuarters, differenceInDays, eachDayOfInterval, eachMonthOfInterval, eachWeekOfInterval, endOfDay, endOfMonth, endOfQuarter, endOfWeek, endOfYear, format, fromUnixTime, getDaysInMonth, getUnixTime, getWeek, isToday, isWeekend, setDate, startOfDay, startOfMonth, startOfQuarter, startOfWeek, startOfYear } from 'date-fns';
@@ -11,6 +11,7 @@ import { coerceBooleanProperty, coerceCssPixelValue } from '@angular/cdk/coercio
11
11
  import * as i1 from '@angular/cdk/drag-drop';
12
12
  import { DragDropModule } from '@angular/cdk/drag-drop';
13
13
  import html2canvas from 'html2canvas';
14
+ import { __decorate, __param } from 'tslib';
14
15
 
15
16
  class GanttDatePoint {
16
17
  constructor(start, text, x, y, additions) {
@@ -204,6 +205,25 @@ var GanttViewType;
204
205
  GanttViewType["week"] = "week";
205
206
  })(GanttViewType || (GanttViewType = {}));
206
207
 
208
+ var GanttLinkType;
209
+ (function (GanttLinkType) {
210
+ GanttLinkType[GanttLinkType["fs"] = 1] = "fs";
211
+ GanttLinkType[GanttLinkType["ff"] = 2] = "ff";
212
+ GanttLinkType[GanttLinkType["ss"] = 3] = "ss";
213
+ GanttLinkType[GanttLinkType["sf"] = 4] = "sf";
214
+ })(GanttLinkType || (GanttLinkType = {}));
215
+ var GanttLinkLineType;
216
+ (function (GanttLinkLineType) {
217
+ GanttLinkLineType["curve"] = "curve";
218
+ GanttLinkLineType["straight"] = "straight";
219
+ })(GanttLinkLineType || (GanttLinkLineType = {}));
220
+ var LinkColors;
221
+ (function (LinkColors) {
222
+ LinkColors["default"] = "#cacaca";
223
+ LinkColors["blocked"] = "#FF7575";
224
+ LinkColors["active"] = "#348FE4";
225
+ })(LinkColors || (LinkColors = {}));
226
+
207
227
  var GanttItemType;
208
228
  (function (GanttItemType) {
209
229
  GanttItemType["bar"] = "bar";
@@ -215,7 +235,17 @@ class GanttItemInternal {
215
235
  this.refs$ = new BehaviorSubject(null);
216
236
  this.origin = item;
217
237
  this.id = this.origin.id;
218
- this.links = this.origin.links || [];
238
+ this.links = (this.origin.links || []).map((link) => {
239
+ if (typeof link === 'string') {
240
+ return {
241
+ type: GanttLinkType.fs,
242
+ link
243
+ };
244
+ }
245
+ else {
246
+ return link;
247
+ }
248
+ });
219
249
  this.color = this.origin.color;
220
250
  this.barStyle = this.origin.barStyle;
221
251
  this.linkable = this.origin.linkable === undefined ? true : this.origin.linkable;
@@ -273,8 +303,9 @@ class GanttItemInternal {
273
303
  this.expanded = expanded;
274
304
  this.origin.expanded = expanded;
275
305
  }
276
- addLink(linkId) {
277
- this.links = [...this.links, linkId];
306
+ addLink(link) {
307
+ console.log(link);
308
+ this.links = [...this.links, link];
278
309
  this.origin.links = this.links;
279
310
  }
280
311
  }
@@ -303,7 +334,12 @@ const defaultConfig = {
303
334
  quarter: 'QQQ',
304
335
  year: 'yyyy年',
305
336
  yearMonth: 'yyyy年MM月',
306
- yearQuarter: 'yyyy年QQQ',
337
+ yearQuarter: 'yyyy年QQQ'
338
+ },
339
+ linkOptions: {
340
+ dependencyTypes: [GanttLinkType.fs],
341
+ showArrow: false,
342
+ lineType: GanttLinkLineType.curve
307
343
  }
308
344
  };
309
345
  const GANTT_GLOBAL_CONFIG = new InjectionToken('GANTT_GLOBAL_CONFIG');
@@ -777,6 +813,12 @@ class GanttUpper {
777
813
  this._multiple = false;
778
814
  this.ganttClass = true;
779
815
  }
816
+ set linkOptions(options) {
817
+ this._linkOptions = options;
818
+ }
819
+ get linkOptions() {
820
+ return Object.assign({}, defaultConfig.linkOptions, this.config.linkOptions, this._linkOptions);
821
+ }
780
822
  set selectable(value) {
781
823
  var _a;
782
824
  this._selectable = coerceBooleanProperty(value);
@@ -998,7 +1040,7 @@ class GanttUpper {
998
1040
  }
999
1041
  }
1000
1042
  GanttUpper.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: GanttUpper, deps: [{ token: i0.ElementRef }, { token: i0.ChangeDetectorRef }, { token: i0.NgZone }, { token: GANTT_GLOBAL_CONFIG }], target: i0.ɵɵFactoryTarget.Directive });
1001
- GanttUpper.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.1.2", type: GanttUpper, inputs: { originItems: ["items", "originItems"], originGroups: ["groups", "originGroups"], viewType: "viewType", start: "start", end: "end", showTodayLine: "showTodayLine", draggable: "draggable", styles: "styles", viewOptions: "viewOptions", disabledLoadOnScroll: "disabledLoadOnScroll", selectable: "selectable", multiple: "multiple" }, outputs: { loadOnScroll: "loadOnScroll", dragStarted: "dragStarted", dragMoved: "dragMoved", dragEnded: "dragEnded", barClick: "barClick" }, host: { properties: { "class.gantt": "this.ganttClass" } }, queries: [{ propertyName: "barTemplate", first: true, predicate: ["bar"], descendants: true, static: true }, { propertyName: "rangeTemplate", first: true, predicate: ["range"], descendants: true, static: true }, { propertyName: "itemTemplate", first: true, predicate: ["item"], descendants: true, static: true }, { propertyName: "groupTemplate", first: true, predicate: ["group"], descendants: true, static: true }, { propertyName: "groupHeaderTemplate", first: true, predicate: ["groupHeader"], descendants: true, static: true }], ngImport: i0 });
1043
+ GanttUpper.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "12.0.0", version: "12.1.2", type: GanttUpper, inputs: { originItems: ["items", "originItems"], originGroups: ["groups", "originGroups"], viewType: "viewType", start: "start", end: "end", showTodayLine: "showTodayLine", draggable: "draggable", styles: "styles", viewOptions: "viewOptions", linkOptions: "linkOptions", disabledLoadOnScroll: "disabledLoadOnScroll", selectable: "selectable", multiple: "multiple" }, outputs: { loadOnScroll: "loadOnScroll", dragStarted: "dragStarted", dragMoved: "dragMoved", dragEnded: "dragEnded", barClick: "barClick" }, host: { properties: { "class.gantt": "this.ganttClass" } }, queries: [{ propertyName: "barTemplate", first: true, predicate: ["bar"], descendants: true, static: true }, { propertyName: "rangeTemplate", first: true, predicate: ["range"], descendants: true, static: true }, { propertyName: "itemTemplate", first: true, predicate: ["item"], descendants: true, static: true }, { propertyName: "groupTemplate", first: true, predicate: ["group"], descendants: true, static: true }, { propertyName: "groupHeaderTemplate", first: true, predicate: ["groupHeader"], descendants: true, static: true }], ngImport: i0 });
1002
1044
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: GanttUpper, decorators: [{
1003
1045
  type: Directive
1004
1046
  }], ctorParameters: function () { return [{ type: i0.ElementRef }, { type: i0.ChangeDetectorRef }, { type: i0.NgZone }, { type: undefined, decorators: [{
@@ -1024,6 +1066,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.2", ngImpor
1024
1066
  type: Input
1025
1067
  }], viewOptions: [{
1026
1068
  type: Input
1069
+ }], linkOptions: [{
1070
+ type: Input
1027
1071
  }], disabledLoadOnScroll: [{
1028
1072
  type: Input
1029
1073
  }], selectable: [{
@@ -1532,63 +1576,77 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.2", ngImpor
1532
1576
  type: Injectable
1533
1577
  }], ctorParameters: function () { return []; } });
1534
1578
 
1579
+ function getDependencyType(path, dependencyTypes) {
1580
+ if (dependencyTypes.includes(GanttLinkType.ss) && path.from.pos === InBarPosition.start && path.to.pos === InBarPosition.start) {
1581
+ return GanttLinkType.ss;
1582
+ }
1583
+ if (dependencyTypes.includes(GanttLinkType.ff) && path.from.pos === InBarPosition.finish && path.to.pos === InBarPosition.finish) {
1584
+ return GanttLinkType.ff;
1585
+ }
1586
+ if (dependencyTypes.includes(GanttLinkType.sf) && path.from.pos === InBarPosition.start && path.to.pos === InBarPosition.finish) {
1587
+ return GanttLinkType.sf;
1588
+ }
1589
+ return GanttLinkType.fs;
1590
+ }
1591
+ var InBarPosition;
1592
+ (function (InBarPosition) {
1593
+ InBarPosition["start"] = "start";
1594
+ InBarPosition["finish"] = "finish";
1595
+ })(InBarPosition || (InBarPosition = {}));
1535
1596
  class GanttDragContainer {
1536
- constructor() {
1597
+ constructor(ganttUpper) {
1598
+ this.ganttUpper = ganttUpper;
1537
1599
  this.dragStarted = new EventEmitter();
1538
1600
  this.dragMoved = new EventEmitter();
1539
1601
  this.dragEnded = new EventEmitter();
1540
1602
  this.linkDragStarted = new EventEmitter();
1541
1603
  this.linkDragEntered = new EventEmitter();
1542
1604
  this.linkDragEnded = new EventEmitter();
1605
+ this.linkDragPath = { from: null, to: null };
1543
1606
  }
1544
- emitLinkDragStarted(from, item) {
1545
- this.linkDraggingId = item.id;
1546
- this.linkDragFrom = from;
1547
- this.linkDragSource = this.linkDragFrom === 'source' ? item : null;
1548
- this.linkDragTarget = this.linkDragFrom === 'target' ? item : null;
1607
+ emitLinkDragStarted(from) {
1608
+ this.linkDraggingId = from.item.id;
1609
+ this.linkDragPath.from = from;
1549
1610
  this.linkDragStarted.emit({
1550
- source: this.linkDragSource && this.linkDragSource.origin,
1551
- target: this.linkDragTarget && this.linkDragTarget.origin
1611
+ source: from.item.origin,
1612
+ target: null
1552
1613
  });
1553
1614
  }
1554
- emitLinkDragEntered(item) {
1555
- if (this.linkDragFrom === 'source') {
1556
- this.linkDragTarget = item;
1557
- }
1558
- else {
1559
- this.linkDragSource = item;
1560
- }
1615
+ emitLinkDragEntered(to) {
1616
+ this.linkDragPath.to = to;
1561
1617
  this.linkDragEntered.emit({
1562
- source: this.linkDragSource.origin,
1563
- target: this.linkDragTarget.origin
1618
+ source: this.linkDragPath.from.item.origin,
1619
+ target: to.item.origin
1564
1620
  });
1565
1621
  }
1566
1622
  emitLinkDragLeaved() {
1567
- if (this.linkDragFrom === 'source') {
1568
- this.linkDragTarget = null;
1569
- }
1570
- else {
1571
- this.linkDragSource = null;
1572
- }
1623
+ this.linkDragPath.to = null;
1573
1624
  }
1574
- emitLinkDragEnded() {
1625
+ emitLinkDragEnded(to) {
1626
+ var _a;
1627
+ this.linkDragPath.to = to;
1628
+ const dependencyType = getDependencyType(this.linkDragPath, (_a = this.ganttUpper.linkOptions) === null || _a === void 0 ? void 0 : _a.dependencyTypes);
1629
+ this.linkDragPath.from.item.addLink({
1630
+ link: this.linkDragPath.to.item.id,
1631
+ type: dependencyType
1632
+ });
1633
+ this.linkDragEnded.emit({
1634
+ source: this.linkDragPath.from.item.origin,
1635
+ target: this.linkDragPath.to.item.origin,
1636
+ type: dependencyType
1637
+ });
1575
1638
  this.linkDraggingId = null;
1576
- if (this.linkDragSource && this.linkDragTarget) {
1577
- this.linkDragSource.addLink(this.linkDragTarget.id);
1578
- this.linkDragEnded.emit({
1579
- source: this.linkDragSource.origin,
1580
- target: this.linkDragTarget.origin
1581
- });
1582
- }
1583
- this.linkDragSource = null;
1584
- this.linkDragTarget = null;
1639
+ this.linkDragPath = { from: null, to: null };
1585
1640
  }
1586
1641
  }
1587
- GanttDragContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: GanttDragContainer, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
1642
+ GanttDragContainer.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: GanttDragContainer, deps: [{ token: GANTT_UPPER_TOKEN }], target: i0.ɵɵFactoryTarget.Injectable });
1588
1643
  GanttDragContainer.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: GanttDragContainer });
1589
1644
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: GanttDragContainer, decorators: [{
1590
1645
  type: Injectable
1591
- }], ctorParameters: function () { return []; } });
1646
+ }], ctorParameters: function () { return [{ type: GanttUpper, decorators: [{
1647
+ type: Inject,
1648
+ args: [GANTT_UPPER_TOKEN]
1649
+ }] }]; } });
1592
1650
 
1593
1651
  class GanttPrintService {
1594
1652
  constructor() { }
@@ -1884,12 +1942,186 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.2", ngImpor
1884
1942
  args: ['mainTemplate', { static: true }]
1885
1943
  }] } });
1886
1944
 
1887
- var LinkColors;
1888
- (function (LinkColors) {
1889
- LinkColors["default"] = "#cacaca";
1890
- LinkColors["blocked"] = "#FF7575";
1891
- LinkColors["active"] = "#348FE4";
1892
- })(LinkColors || (LinkColors = {}));
1945
+ class GanttLinkLine {
1946
+ constructor() { }
1947
+ generatePath(source, target, type) {
1948
+ if (source.before && source.after && target.before && target.after) {
1949
+ let path = '';
1950
+ switch (type) {
1951
+ case GanttLinkType.ss:
1952
+ path = this.generateSSPath(source, target);
1953
+ break;
1954
+ case GanttLinkType.ff:
1955
+ path = this.generateFFPath(source, target);
1956
+ break;
1957
+ case GanttLinkType.sf:
1958
+ path = this.generateFSAndSFPath(source, target, type);
1959
+ break;
1960
+ default:
1961
+ path = this.generateFSAndSFPath(source, target);
1962
+ }
1963
+ return path;
1964
+ }
1965
+ }
1966
+ }
1967
+
1968
+ let GanttLinkLineCurve = class GanttLinkLineCurve extends GanttLinkLine {
1969
+ constructor(ganttUpper) {
1970
+ super();
1971
+ this.ganttUpper = ganttUpper;
1972
+ }
1973
+ generateSSPath(source, target) {
1974
+ const x1 = source.before.x;
1975
+ const y1 = source.before.y;
1976
+ const x4 = target.before.x;
1977
+ const y4 = target.before.y;
1978
+ const isMirror = y4 > y1 ? 0 : 1;
1979
+ const radius = Math.abs(y4 - y1) / 2;
1980
+ if (x4 > x1) {
1981
+ return `M ${x1} ${y1}
1982
+ A ${radius} ${radius} 0 1 ${isMirror} ${x1} ${y4}
1983
+ L ${x4} ${y4}`;
1984
+ }
1985
+ else {
1986
+ return `M ${x1} ${y1}
1987
+ L ${x4} ${y1}
1988
+ A ${radius} ${radius} 0 1 ${isMirror} ${x4} ${y4}`;
1989
+ }
1990
+ }
1991
+ generateFFPath(source, target) {
1992
+ const x1 = source.after.x;
1993
+ const y1 = source.after.y;
1994
+ const x4 = target.after.x;
1995
+ const y4 = target.after.y;
1996
+ const isMirror = y4 > y1 ? 1 : 0;
1997
+ const radius = Math.abs(y4 - y1) / 2;
1998
+ if (x4 > x1) {
1999
+ return `M ${x1} ${y1}
2000
+ L ${x4} ${y1}
2001
+ A ${radius} ${radius} 0 1 ${isMirror} ${x4} ${y4}`;
2002
+ }
2003
+ else {
2004
+ return `M ${x1} ${y1}
2005
+ A ${radius} ${radius} 0 1 ${isMirror} ${x1} ${y4}
2006
+ L ${x4} ${y4}`;
2007
+ }
2008
+ }
2009
+ generateFSAndSFPath(source, target, type) {
2010
+ var _a;
2011
+ let x1 = source.after.x;
2012
+ let y1 = source.after.y;
2013
+ let x4 = target.before.x;
2014
+ let y4 = target.before.y;
2015
+ const bezierWeight = 0.5;
2016
+ if (type === GanttLinkType.sf) {
2017
+ x1 = target.after.x;
2018
+ y1 = target.after.y;
2019
+ x4 = source.before.x;
2020
+ y4 = source.before.y;
2021
+ }
2022
+ let dx = Math.abs(x4 - x1) * bezierWeight;
2023
+ let x2 = x1 + dx;
2024
+ let x3 = x4 - dx;
2025
+ const centerX = (x1 + x4) / 2;
2026
+ const centerY = (y1 + y4) / 2;
2027
+ let controlX = this.ganttUpper.styles.lineHeight / 2;
2028
+ const controlY = this.ganttUpper.styles.lineHeight / 2;
2029
+ if (x1 >= x4) {
2030
+ if (Math.abs(y4 - y1) <= this.ganttUpper.styles.lineHeight) {
2031
+ return `M ${x1} ${y1}
2032
+ C ${x1 + controlX} ${y1} ${x1 + controlX} ${y4 > y1 ? y1 + controlX : y1 - controlX} ${x1} ${y4 > y1 ? y1 + controlY : y1 - controlY}
2033
+ L ${x4} ${y4 > y1 ? y4 - controlY : y4 + controlY}
2034
+ C ${x4 - controlY} ${y4 > y1 ? y4 - controlY : y4 + controlY} ${x4 - controlX} ${y4} ${x4} ${y4}
2035
+ `;
2036
+ }
2037
+ else {
2038
+ controlX = this.ganttUpper.styles.lineHeight;
2039
+ return `M ${x1} ${y1}
2040
+ C ${x1 + controlX} ${y1} ${x1 + controlX} ${y4 > y1 ? y1 + controlX : y1 - controlX} ${centerX} ${centerY}
2041
+ C ${x4 - controlX} ${y4 > y1 ? y4 - controlX : y4 + controlX} ${x4 - controlX} ${y4} ${x4} ${y4}
2042
+ `;
2043
+ }
2044
+ }
2045
+ else if (((_a = this.ganttUpper.linkOptions) === null || _a === void 0 ? void 0 : _a.showArrow) && x4 - x1 < 200) {
2046
+ dx = Math.max(Math.abs(y4 - y1) * bezierWeight, 60);
2047
+ x2 = x1 + dx;
2048
+ x3 = x4 - dx;
2049
+ return `M ${x1} ${y1} C ${x2} ${y1} ${x3} ${y4} ${x4} ${y4}`;
2050
+ }
2051
+ return `M ${x1} ${y1} C ${x2} ${y1} ${x3} ${y4} ${x4} ${y4}`;
2052
+ }
2053
+ };
2054
+ GanttLinkLineCurve = __decorate([
2055
+ __param(0, Inject(GANTT_UPPER_TOKEN))
2056
+ ], GanttLinkLineCurve);
2057
+
2058
+ class GanttLinkLineStraight extends GanttLinkLine {
2059
+ constructor() {
2060
+ super();
2061
+ this.pathControl = 20;
2062
+ }
2063
+ generateSSPath(source, target) {
2064
+ const x1 = source.before.x;
2065
+ const y1 = source.before.y;
2066
+ const x4 = target.before.x;
2067
+ const y4 = target.before.y;
2068
+ const control = this.pathControl;
2069
+ return `M ${x1} ${y1}
2070
+ L ${x4 > x1 ? x1 - control : x4 - control} ${y1}
2071
+ L ${x4 > x1 ? x1 - control : x4 - control} ${y4}
2072
+ L ${x4} ${y4}`;
2073
+ }
2074
+ generateFFPath(source, target) {
2075
+ const x1 = source.after.x;
2076
+ const y1 = source.after.y;
2077
+ const x4 = target.after.x;
2078
+ const y4 = target.after.y;
2079
+ const control = this.pathControl;
2080
+ return `M ${x1} ${y1}
2081
+ L ${x4 > x1 ? x4 + control : x1 + control} ${y1}
2082
+ L ${x4 > x1 ? x4 + control : x1 + control} ${y4}
2083
+ L ${x4} ${y4}`;
2084
+ }
2085
+ generateFSAndSFPath(source, target, type) {
2086
+ let x1 = source.after.x;
2087
+ let y1 = source.after.y;
2088
+ let x4 = target.before.x;
2089
+ let y4 = target.before.y;
2090
+ const control = this.pathControl;
2091
+ if (type === GanttLinkType.sf) {
2092
+ x1 = target.after.x;
2093
+ y1 = target.after.y;
2094
+ x4 = source.before.x;
2095
+ y4 = source.before.y;
2096
+ }
2097
+ if (x4 - x1 >= 40) {
2098
+ return `M ${x1} ${y1}
2099
+ L ${x1 + control} ${y1}
2100
+ L ${x1 + control} ${y4}
2101
+ L ${x4} ${y4}`;
2102
+ }
2103
+ else {
2104
+ return `M ${x1} ${y1}
2105
+ L ${x1 + control} ${y1}
2106
+ L ${x1 + control} ${y4 > y1 ? y1 + control : y1 - control}
2107
+ L ${x4 - control} ${y4 > y1 ? y1 + control : y1 - control}
2108
+ L ${x4 - control} ${y4}
2109
+ L ${x4} ${y4}`;
2110
+ }
2111
+ }
2112
+ }
2113
+
2114
+ function createLineGenerator(type, ganttUpper) {
2115
+ switch (type) {
2116
+ case GanttLinkLineType.curve:
2117
+ return new GanttLinkLineCurve(ganttUpper);
2118
+ case GanttLinkLineType.straight:
2119
+ return new GanttLinkLineStraight();
2120
+ default:
2121
+ throw new Error('gantt link path type invalid');
2122
+ }
2123
+ }
2124
+
1893
2125
  class GanttLinksComponent {
1894
2126
  constructor(ganttUpper, cdr, elementRef, ganttDragContainer) {
1895
2127
  this.ganttUpper = ganttUpper;
@@ -1900,20 +2132,23 @@ class GanttLinksComponent {
1900
2132
  this.items = [];
1901
2133
  this.lineClick = new EventEmitter();
1902
2134
  this.links = [];
2135
+ this.ganttLinkTypes = GanttLinkType;
2136
+ this.showArrow = false;
1903
2137
  this.linkItems = [];
1904
- this.bezierWeight = -0.5;
1905
2138
  this.firstChange = true;
1906
2139
  this.unsubscribe$ = new Subject();
1907
2140
  this.ganttLinksOverlay = true;
1908
2141
  }
1909
2142
  ngOnInit() {
2143
+ this.linkLine = createLineGenerator(this.ganttUpper.linkOptions.lineType, this.ganttUpper);
2144
+ this.showArrow = this.ganttUpper.linkOptions.showArrow;
1910
2145
  this.buildLinks();
1911
2146
  this.firstChange = false;
1912
2147
  this.ganttDragContainer.dragStarted.pipe(takeUntil(this.unsubscribe$)).subscribe(() => {
1913
2148
  this.elementRef.nativeElement.style.visibility = 'hidden';
1914
2149
  });
1915
2150
  merge(this.ganttUpper.viewChange, this.ganttUpper.expandChange, this.ganttUpper.view.start$, this.ganttUpper.dragEnded, this.ganttUpper.linkDragEnded)
1916
- .pipe(takeUntil(this.unsubscribe$), skip(1))
2151
+ .pipe(takeUntil(this.unsubscribe$), skip(1), debounceTime(0))
1917
2152
  .subscribe(() => {
1918
2153
  this.elementRef.nativeElement.style.visibility = 'visible';
1919
2154
  this.buildLinks();
@@ -1964,77 +2199,24 @@ class GanttLinksComponent {
1964
2199
  });
1965
2200
  }
1966
2201
  }
1967
- generatePath(source, target) {
1968
- if (source.before && source.after && target.before && target.after) {
1969
- const x1 = source.after.x;
1970
- const y1 = source.after.y;
1971
- const x4 = target.before.x;
1972
- const y4 = target.before.y;
1973
- const dx = Math.abs(x4 - x1) * this.bezierWeight;
1974
- const x2 = x1 - dx;
1975
- const x3 = x4 + dx;
1976
- const centerX = (x1 + x4) / 2;
1977
- const centerY = (y1 + y4) / 2;
1978
- let controlX = this.ganttUpper.styles.lineHeight / 2;
1979
- const controlY = this.ganttUpper.styles.lineHeight / 2;
1980
- if (x1 >= x4) {
1981
- if (y4 > y1) {
1982
- if (Math.abs(y4 - y1) <= this.ganttUpper.styles.lineHeight) {
1983
- return `M ${x1} ${y1}
1984
- C ${x1 + controlX} ${y1} ${x1 + controlX} ${y1 + controlX} ${x1} ${y1 + controlY}
1985
- L ${x1} ${y1 + controlY} ${centerX} ${centerY}
1986
-
1987
- M ${x4} ${y4}
1988
- C ${x4 - controlX} ${y4} ${x4 - controlX} ${y4 - controlX} ${x4} ${y4 - controlY}
1989
- L ${x4} ${y4 - controlY} ${centerX} ${centerY}`;
1990
- }
1991
- else {
1992
- controlX = this.ganttUpper.styles.lineHeight;
1993
- return `M ${x1} ${y1}
1994
- C ${x1 + controlX} ${y1} ${x1 + controlX} ${y1 + controlX} ${centerX} ${centerY}
1995
-
1996
-
1997
- M ${x4} ${y4}
1998
- C ${x4 - controlX} ${y4} ${x4 - controlX} ${y4 - controlX} ${centerX} ${centerY}`;
1999
- }
2000
- }
2001
- else {
2002
- if (Math.abs(y4 - y1) <= this.ganttUpper.styles.lineHeight) {
2003
- return `M ${x1} ${y1}
2004
- C ${x1 + controlX} ${y1} ${x1 + controlX} ${y1 - controlX} ${x1} ${y1 - controlY}
2005
- L ${x1} ${y1 - controlY} ${centerX} ${centerY}
2006
-
2007
- M ${x4} ${y4}
2008
- C ${x4 - controlX} ${y4} ${x4 - controlX} ${y4 + controlX} ${x4} ${y4 + controlY}
2009
- L ${x4} ${y4 + controlY} ${centerX} ${centerY}
2010
- `;
2011
- }
2012
- else {
2013
- controlX = this.ganttUpper.styles.lineHeight;
2014
- return `M ${x1} ${y1}
2015
- C ${x1 + controlX} ${y1} ${x1 + controlX} ${y1 - controlX} ${centerX} ${centerY}
2016
-
2017
- M ${x4} ${y4}
2018
- C ${x4 - controlX} ${y4} ${x4 - controlX} ${y4 + controlX} ${centerX} ${centerY}`;
2019
- }
2020
- }
2021
- }
2022
- return `M ${x1} ${y1} C ${x2} ${y1} ${x3} ${y4} ${x4} ${y4}`;
2023
- }
2024
- }
2025
2202
  buildLinks() {
2026
2203
  this.computeItemPosition();
2027
2204
  this.links = [];
2028
2205
  this.linkItems.forEach((source) => {
2029
2206
  if (source.origin.start || source.origin.end) {
2030
- source.links.forEach((linkId) => {
2031
- const target = this.linkItems.find((item) => item.id === linkId);
2207
+ source.links.forEach((link) => {
2208
+ const target = this.linkItems.find((item) => item.id === link.link);
2032
2209
  if (target && (target.origin.start || target.origin.end)) {
2210
+ let color = LinkColors.default;
2211
+ if (link.type === GanttLinkType.fs && source.end.getTime() > target.start.getTime()) {
2212
+ color = LinkColors.blocked;
2213
+ }
2033
2214
  this.links.push({
2034
- path: this.generatePath(source, target),
2215
+ path: this.linkLine.generatePath(source, target, link.type),
2035
2216
  source: source.origin,
2036
2217
  target: target.origin,
2037
- color: source.end.getTime() > target.start.getTime() ? LinkColors.blocked : LinkColors.default
2218
+ type: link.type,
2219
+ color: link.color || color
2038
2220
  });
2039
2221
  }
2040
2222
  });
@@ -2067,7 +2249,7 @@ class GanttLinksComponent {
2067
2249
  }
2068
2250
  }
2069
2251
  GanttLinksComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: GanttLinksComponent, deps: [{ token: GANTT_UPPER_TOKEN }, { token: i0.ChangeDetectorRef }, { token: i0.ElementRef }, { token: GanttDragContainer }], target: i0.ɵɵFactoryTarget.Component });
2070
- GanttLinksComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.2", type: GanttLinksComponent, selector: "gantt-links-overlay", inputs: { groups: "groups", items: "items" }, outputs: { lineClick: "lineClick" }, host: { properties: { "class.gantt-links-overlay": "this.ganttLinksOverlay" } }, usesOnChanges: true, ngImport: i0, template: "<svg [attr.width]=\"ganttUpper.view.width\" class=\"gantt-links-overlay-main\">\n <ng-container *ngFor=\"let link of links; let i = index; trackBy: trackBy\">\n <path [attr.d]=\"link.path\" fill=\"transparent\" stroke-width=\"2\" [attr.stroke]=\"link.color\" pointer-events=\"none\"></path>\n <g>\n <path\n class=\"link-line\"\n (click)=\"onLineClick($event, link)\"\n (mouseenter)=\"mouseEnterPath(link)\"\n (mouseleave)=\"mouseLeavePath(link)\"\n [attr.d]=\"link.path\"\n stroke=\"transparent\"\n stroke-width=\"9\"\n fill=\"none\"\n cursor=\"pointer\"\n ></path>\n </g>\n </ng-container>\n <line class=\"link-dragging-line\"></line>\n</svg>\n", directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }] });
2252
+ GanttLinksComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "12.0.0", version: "12.1.2", type: GanttLinksComponent, selector: "gantt-links-overlay", inputs: { groups: "groups", items: "items" }, outputs: { lineClick: "lineClick" }, host: { properties: { "class.gantt-links-overlay": "this.ganttLinksOverlay" } }, usesOnChanges: true, ngImport: i0, template: "<svg [attr.width]=\"ganttUpper.view.width\" class=\"gantt-links-overlay-main\">\n <ng-container *ngFor=\"let link of links; let i = index; trackBy: trackBy\">\n <path\n [attr.d]=\"link.path\"\n fill=\"transparent\"\n stroke-width=\"2\"\n [attr.stroke]=\"link.color\"\n pointer-events=\"none\"\n [attr.style]=\"link.type === ganttLinkTypes.sf ? 'marker-start: url(#triangle' + i + ')' : 'marker-end: url(#triangle' + i + ')'\"\n ></path>\n <g>\n <path\n class=\"link-line\"\n (click)=\"onLineClick($event, link)\"\n (mouseenter)=\"mouseEnterPath(link)\"\n (mouseleave)=\"mouseLeavePath(link)\"\n [attr.d]=\"link.path\"\n stroke=\"transparent\"\n stroke-width=\"9\"\n fill=\"none\"\n cursor=\"pointer\"\n ></path>\n </g>\n <defs *ngIf=\"showArrow\">\n <marker\n *ngIf=\"link.type === ganttLinkTypes.sf; else markerEnd\"\n [id]=\"'triangle' + i\"\n markerUnits=\"strokeWidth\"\n markerWidth=\"5\"\n markerHeight=\"4\"\n refX=\"5\"\n refY=\"2\"\n orient=\"180\"\n >\n <path [attr.fill]=\"link.color\" [attr.stroke]=\"link.color\" d=\"M 0 0 L 5 2 L 0 4 z\" />\n </marker>\n\n <ng-template #markerEnd>\n <marker [id]=\"'triangle' + i\" markerUnits=\"strokeWidth\" markerWidth=\"5\" markerHeight=\"4\" refX=\"5\" refY=\"2\" orient=\"auto\">\n <path [attr.fill]=\"link.color\" [attr.stroke]=\"link.color\" d=\"M 0 0 L 5 2 L 0 4 z\" />\n </marker>\n </ng-template>\n </defs>\n </ng-container>\n <line class=\"link-dragging-line\"></line>\n</svg>\n", directives: [{ type: i2.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { type: i2.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }] });
2071
2253
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.2", ngImport: i0, type: GanttLinksComponent, decorators: [{
2072
2254
  type: Component,
2073
2255
  args: [{
@@ -2171,7 +2353,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.2", ngImpor
2171
2353
 
2172
2354
  const dragMinWidth = 10;
2173
2355
  const activeClass = 'gantt-bar-active';
2174
- const linkDropClass = 'gantt-bar-link-drop';
2356
+ const dropActiveClass = 'gantt-bar-drop-active';
2357
+ const singleDropActiveClass = 'gantt-bar-single-drop-active';
2175
2358
  function createSvgElement(qualifiedName, className) {
2176
2359
  const element = document.createElementNS('http://www.w3.org/2000/svg', qualifiedName);
2177
2360
  element.classList.add(className);
@@ -2192,13 +2375,21 @@ class GanttBarDrag {
2192
2375
  return !this.item.linkable || !this.ganttUpper.linkable;
2193
2376
  }
2194
2377
  createMouseEvents() {
2378
+ var _a, _b, _c;
2379
+ const dropClass = ((_b = (_a = this.ganttUpper.config.linkOptions) === null || _a === void 0 ? void 0 : _a.dependencyTypes) === null || _b === void 0 ? void 0 : _b.length) === 1 &&
2380
+ ((_c = this.ganttUpper.config.linkOptions) === null || _c === void 0 ? void 0 : _c.dependencyTypes[0]) === GanttLinkType.fs
2381
+ ? singleDropActiveClass
2382
+ : dropActiveClass;
2195
2383
  fromEvent(this.barElement, 'mouseenter')
2196
2384
  .pipe(takeUntil(this.destroy$))
2197
- .subscribe(() => {
2385
+ .subscribe((event) => {
2198
2386
  if (this.dragContainer.linkDraggingId && this.dragContainer.linkDraggingId !== this.item.id) {
2199
2387
  if (this.item.linkable) {
2200
- this.barElement.classList.add(linkDropClass);
2201
- this.dragContainer.emitLinkDragEntered(this.item);
2388
+ this.barElement.classList.add(dropClass);
2389
+ this.dragContainer.emitLinkDragEntered({
2390
+ item: this.item,
2391
+ element: this.barElement
2392
+ });
2202
2393
  }
2203
2394
  }
2204
2395
  else {
@@ -2207,14 +2398,14 @@ class GanttBarDrag {
2207
2398
  });
2208
2399
  fromEvent(this.barElement, 'mouseleave')
2209
2400
  .pipe(takeUntil(this.destroy$))
2210
- .subscribe(() => {
2401
+ .subscribe((event) => {
2211
2402
  if (!this.dragContainer.linkDraggingId) {
2212
2403
  this.barElement.classList.remove(activeClass);
2213
2404
  }
2214
2405
  else {
2215
2406
  this.dragContainer.emitLinkDragLeaved();
2216
2407
  }
2217
- this.barElement.classList.remove(linkDropClass);
2408
+ this.barElement.classList.remove(dropClass);
2218
2409
  });
2219
2410
  }
2220
2411
  createBarDrag() {
@@ -2225,19 +2416,22 @@ class GanttBarDrag {
2225
2416
  this.dragContainer.dragStarted.emit({ item: this.item.origin });
2226
2417
  });
2227
2418
  dragRef.moved.subscribe((event) => {
2228
- const x = this.item.refs.x + event.distance.x;
2229
- const days = differenceInCalendarDays(this.item.end.value, this.item.start.value);
2230
- const start = this.ganttUpper.view.getDateByXPoint(x);
2231
- const end = start.addDays(days);
2232
- this.openDragBackdrop(this.barElement, this.ganttUpper.view.getDateByXPoint(x), end);
2419
+ const currentX = this.item.refs.x + event.distance.x;
2420
+ const currentDate = this.ganttUpper.view.getDateByXPoint(currentX);
2421
+ const currentStartX = this.ganttUpper.view.getXPointByDate(currentDate);
2422
+ const dayWidth = this.ganttUpper.view.getDayOccupancyWidth(currentDate);
2423
+ const diffDays = differenceInCalendarDays(this.item.end.value, this.item.start.value);
2424
+ let start = currentDate;
2425
+ let end = currentDate.addDays(diffDays);
2426
+ if (currentX > currentStartX + dayWidth / 2) {
2427
+ start = start.addDays(1);
2428
+ end = end.addDays(1);
2429
+ }
2430
+ this.openDragBackdrop(this.barElement, start, end);
2233
2431
  this.item.updateDate(start, end);
2234
2432
  this.dragContainer.dragMoved.emit({ item: this.item.origin });
2235
2433
  });
2236
2434
  dragRef.ended.subscribe((event) => {
2237
- const days = differenceInCalendarDays(this.item.end.value, this.item.start.value);
2238
- const start = this.ganttUpper.view.getDateByXPoint(this.item.refs.x + event.distance.x);
2239
- const end = start.addDays(days);
2240
- this.item.updateDate(start, end);
2241
2435
  this.clearDraggingStyles();
2242
2436
  this.closeDragBackdrop();
2243
2437
  event.source.reset();
@@ -2311,7 +2505,7 @@ class GanttBarDrag {
2311
2505
  const dragRefs = [];
2312
2506
  const handles = this.barElement.querySelectorAll('.link-handles .handle');
2313
2507
  handles.forEach((handle, index) => {
2314
- const isBefore = index === 0;
2508
+ const isBegin = index === 0;
2315
2509
  const dragRef = this.dragDrop.createDrag(handle);
2316
2510
  dragRef.withBoundaryElement(this.dom.root);
2317
2511
  dragRef.beforeStarted.subscribe(() => {
@@ -2320,24 +2514,35 @@ class GanttBarDrag {
2320
2514
  this.barDragRef.disabled = true;
2321
2515
  }
2322
2516
  this.createLinkDraggingLine();
2323
- this.dragContainer.emitLinkDragStarted(isBefore ? 'target' : 'source', this.item);
2517
+ this.dragContainer.emitLinkDragStarted({
2518
+ element: this.barElement,
2519
+ item: this.item,
2520
+ pos: isBegin ? InBarPosition.start : InBarPosition.finish
2521
+ });
2324
2522
  });
2325
2523
  dragRef.moved.subscribe(() => {
2326
- const positions = this.calcLinkLinePositions(handle, isBefore);
2524
+ const positions = this.calcLinkLinePositions(handle, isBegin);
2327
2525
  this.linkDraggingLine.setAttribute('x1', positions.x1.toString());
2328
2526
  this.linkDraggingLine.setAttribute('y1', positions.y1.toString());
2329
2527
  this.linkDraggingLine.setAttribute('x2', positions.x2.toString());
2330
2528
  this.linkDraggingLine.setAttribute('y2', positions.y2.toString());
2331
2529
  });
2332
2530
  dragRef.ended.subscribe((event) => {
2333
- event.source.reset();
2334
2531
  handle.style.pointerEvents = '';
2335
2532
  if (this.barDragRef) {
2336
2533
  this.barDragRef.disabled = false;
2337
2534
  }
2535
+ // 计算line拖动的落点位于目标Bar的值,如果值大于Bar宽度的一半,说明是拖动到Begin位置,否则则为拖动到End位置
2536
+ if (this.dragContainer.linkDragPath.to) {
2537
+ const placePointX = event.source.getRootElement().getBoundingClientRect().x -
2538
+ this.dragContainer.linkDragPath.to.element.getBoundingClientRect().x;
2539
+ this.dragContainer.emitLinkDragEnded(Object.assign(Object.assign({}, this.dragContainer.linkDragPath.to), { pos: placePointX < this.dragContainer.linkDragPath.to.item.refs.width / 2
2540
+ ? InBarPosition.start
2541
+ : InBarPosition.finish }));
2542
+ }
2543
+ event.source.reset();
2338
2544
  this.barElement.classList.remove(activeClass);
2339
2545
  this.destroyLinkDraggingLine();
2340
- this.dragContainer.emitLinkDragEnded();
2341
2546
  });
2342
2547
  dragRefs.push(dragRef);
2343
2548
  });
@@ -2386,6 +2591,7 @@ class GanttBarDrag {
2386
2591
  if (!this.linkDraggingLine) {
2387
2592
  const svgElement = createSvgElement('svg', 'gantt-link-drag-container');
2388
2593
  const linElement = createSvgElement('line', 'link-dragging-line');
2594
+ linElement.style.pointerEvents = 'none';
2389
2595
  svgElement.appendChild(linElement);
2390
2596
  this.dom.root.appendChild(svgElement);
2391
2597
  this.linkDraggingLine = linElement;
@@ -2630,12 +2836,12 @@ class NgxGanttComponent extends GanttUpper {
2630
2836
  this.selectionModel.toggle(selectedValue.id);
2631
2837
  const selectedIds = this.selectionModel.selected;
2632
2838
  if (this.multiple) {
2633
- const selectedValue = this.getGanttItems(selectedIds).map((item) => item.origin);
2634
- this.selectedChange.emit({ event, selectedValue });
2839
+ const _selectedValue = this.getGanttItems(selectedIds).map((item) => item.origin);
2840
+ this.selectedChange.emit({ event, selectedValue: _selectedValue });
2635
2841
  }
2636
2842
  else {
2637
- const selectedValue = (_a = this.getGanttItem(selectedIds[0])) === null || _a === void 0 ? void 0 : _a.origin;
2638
- this.selectedChange.emit({ event, selectedValue });
2843
+ const _selectedValue = (_a = this.getGanttItem(selectedIds[0])) === null || _a === void 0 ? void 0 : _a.origin;
2844
+ this.selectedChange.emit({ event, selectedValue: _selectedValue });
2639
2845
  }
2640
2846
  }
2641
2847
  ngOnDestroy() {
@@ -2775,5 +2981,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "12.1.2", ngImpor
2775
2981
  * Generated bundle index. Do not edit.
2776
2982
  */
2777
2983
 
2778
- export { GANTT_GLOBAL_CONFIG, GANTT_UPPER_TOKEN, GanttBarClickEvent, GanttDate, GanttDatePoint, GanttDragEvent, GanttGroupInternal, GanttItemInternal, GanttItemType, GanttItemUpper, GanttLineClickEvent, GanttLinkDragEvent, GanttLoadOnScrollEvent, GanttPrintService, GanttSelectedEvent, GanttTableEvent, GanttUpper, GanttView, GanttViewType, IsGanttBarItemPipe, IsGanttCustomItemPipe, IsGanttRangeItemPipe, NgxGanttBarComponent, NgxGanttComponent, NgxGanttModule, NgxGanttRangeComponent, NgxGanttRootComponent, NgxGanttTableColumnComponent, NgxGanttTableComponent, defaultConfig, primaryDatePointTop, secondaryDatePointTop };
2984
+ export { GANTT_GLOBAL_CONFIG, GANTT_UPPER_TOKEN, GanttBarClickEvent, GanttDate, GanttDatePoint, GanttDragEvent, GanttGroupInternal, GanttItemInternal, GanttItemType, GanttItemUpper, GanttLineClickEvent, GanttLinkDragEvent, GanttLinkLineType, GanttLinkType, GanttLoadOnScrollEvent, GanttPrintService, GanttSelectedEvent, GanttTableEvent, GanttUpper, GanttView, GanttViewType, IsGanttBarItemPipe, IsGanttCustomItemPipe, IsGanttRangeItemPipe, LinkColors, NgxGanttBarComponent, NgxGanttComponent, NgxGanttModule, NgxGanttRangeComponent, NgxGanttRootComponent, NgxGanttTableColumnComponent, NgxGanttTableComponent, defaultConfig, primaryDatePointTop, secondaryDatePointTop };
2779
2985
  //# sourceMappingURL=worktile-gantt.js.map