gantt-task-react-v 1.2.10 → 1.2.12

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.
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { Distances, ViewMode, Task } from "../../types";
2
+ import { Distances, ViewMode } from "../../types";
3
3
  export type GanttTodayProps = {
4
4
  additionalLeftSpace: number;
5
5
  distances: Distances;
@@ -15,6 +15,7 @@ export type GanttTodayProps = {
15
15
  dataDateColor?: string | null;
16
16
  todayLabel?: string;
17
17
  dataDateLabel?: string;
18
- tasks?: readonly Task[];
18
+ taskHeight?: number;
19
+ taskYOffset?: number;
19
20
  };
20
21
  export declare const GanttToday: React.NamedExoticComponent<GanttTodayProps>;
@@ -10909,222 +10909,9 @@ const styles$c = {
10909
10909
  ganttToday,
10910
10910
  ganttTodayCircle
10911
10911
  };
10912
- const getDateByOffset = (startDate, offset2, viewMode) => {
10913
- switch (viewMode) {
10914
- case ViewMode.Day:
10915
- return addDays(startDate, offset2);
10916
- case ViewMode.HalfDay:
10917
- return addHours(startDate, offset2 * 12);
10918
- case ViewMode.QuarterDay:
10919
- return addHours(startDate, offset2 * 6);
10920
- case ViewMode.Hour:
10921
- return addHours(startDate, offset2);
10922
- case ViewMode.Month:
10923
- return addMonths(startDate, offset2);
10924
- case ViewMode.Week:
10925
- return addWeeks(startDate, offset2);
10926
- case ViewMode.Year:
10927
- return addYears(startDate, offset2);
10928
- default:
10929
- throw new Error("Unknown view mode");
10930
- }
10931
- };
10932
- const taskXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
10933
- const index2 = getDatesDiff(xDate, startDate, viewMode);
10934
- const currentDate = getDateByOffset(startDate, index2, viewMode);
10935
- const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
10936
- const remainderMillis = xDate.getTime() - currentDate.getTime();
10937
- const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
10938
- return index2 * columnWidth + percentOfInterval * columnWidth;
10939
- };
10940
- const taskComparisonXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
10941
- const index2 = getDatesDiff(xDate, startDate, viewMode);
10942
- const currentDate = getDateByOffset(startDate, index2, viewMode);
10943
- const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
10944
- const remainderMillis = xDate.getTime() - currentDate.getTime();
10945
- const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
10946
- return index2 * columnWidth + percentOfInterval * columnWidth;
10947
- };
10948
- const progressWithByParams = (taskX1, taskX2, progress, rtl) => {
10949
- const progressWidth = Math.max((taskX2 - taskX1) * progress * 0.01, 0);
10950
- let progressX;
10951
- if (rtl) {
10952
- progressX = taskX2 - progressWidth;
10953
- } else {
10954
- progressX = taskX1;
10955
- }
10956
- return [progressWidth, progressX];
10957
- };
10958
- const dateByX = (x, taskX, taskDate, xStep, timeStep) => {
10959
- let newDate = new Date((x - taskX) / xStep * timeStep + taskDate.getTime());
10960
- newDate = new Date(
10961
- newDate.getTime() + (newDate.getTimezoneOffset() - taskDate.getTimezoneOffset()) * 6e4
10962
- );
10963
- return newDate;
10964
- };
10965
- const handleTaskBySVGMouseEvent = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
10966
- let result;
10967
- switch (selectedTask.type) {
10968
- case "milestone":
10969
- result = handleTaskBySVGMouseEventForMilestone(
10970
- action,
10971
- selectedTask,
10972
- initialCoordinates,
10973
- coordinates,
10974
- xStep,
10975
- timeStep
10976
- );
10977
- break;
10978
- default:
10979
- result = handleTaskBySVGMouseEventForBar(
10980
- action,
10981
- selectedTask,
10982
- initialCoordinates,
10983
- coordinates,
10984
- xStep,
10985
- timeStep,
10986
- rtl
10987
- );
10988
- break;
10989
- }
10990
- return result;
10991
- };
10992
- const handleTaskBySVGMouseEventForBar = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
10993
- const changedTask = { ...selectedTask };
10994
- let isChanged = false;
10995
- switch (action) {
10996
- case "progress":
10997
- isChanged = initialCoordinates.progressWidth !== coordinates.progressWidth;
10998
- if (isChanged) {
10999
- changedTask.progress = Math.round(
11000
- coordinates.progressWidth * 100 / (coordinates.x2 - coordinates.x1)
11001
- );
11002
- }
11003
- break;
11004
- case "start": {
11005
- isChanged = initialCoordinates.x1 !== coordinates.x1;
11006
- if (isChanged) {
11007
- if (rtl) {
11008
- changedTask.end = dateByX(
11009
- coordinates.x1,
11010
- initialCoordinates.x1,
11011
- selectedTask.end,
11012
- xStep,
11013
- timeStep
11014
- );
11015
- } else {
11016
- changedTask.start = dateByX(
11017
- coordinates.x1,
11018
- initialCoordinates.x1,
11019
- selectedTask.start,
11020
- xStep,
11021
- timeStep
11022
- );
11023
- }
11024
- }
11025
- break;
11026
- }
11027
- case "end": {
11028
- isChanged = initialCoordinates.x2 !== coordinates.x2;
11029
- if (isChanged) {
11030
- if (rtl) {
11031
- changedTask.start = dateByX(
11032
- coordinates.x2,
11033
- initialCoordinates.x2,
11034
- selectedTask.start,
11035
- xStep,
11036
- timeStep
11037
- );
11038
- } else {
11039
- changedTask.end = dateByX(
11040
- coordinates.x2,
11041
- initialCoordinates.x2,
11042
- selectedTask.end,
11043
- xStep,
11044
- timeStep
11045
- );
11046
- }
11047
- }
11048
- break;
11049
- }
11050
- case "move": {
11051
- isChanged = initialCoordinates.x1 !== coordinates.x1;
11052
- if (isChanged) {
11053
- if (rtl) {
11054
- changedTask.end = dateByX(
11055
- coordinates.x1,
11056
- initialCoordinates.x1,
11057
- selectedTask.end,
11058
- xStep,
11059
- timeStep
11060
- );
11061
- changedTask.start = dateByX(
11062
- coordinates.x2,
11063
- initialCoordinates.x2,
11064
- selectedTask.start,
11065
- xStep,
11066
- timeStep
11067
- );
11068
- } else {
11069
- changedTask.start = dateByX(
11070
- coordinates.x1,
11071
- initialCoordinates.x1,
11072
- selectedTask.start,
11073
- xStep,
11074
- timeStep
11075
- );
11076
- changedTask.end = dateByX(
11077
- coordinates.x2,
11078
- initialCoordinates.x2,
11079
- selectedTask.end,
11080
- xStep,
11081
- timeStep
11082
- );
11083
- }
11084
- }
11085
- break;
11086
- }
11087
- }
11088
- return { isChanged, changedTask };
11089
- };
11090
- const handleTaskBySVGMouseEventForMilestone = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep) => {
11091
- const changedTask = { ...selectedTask };
11092
- const isChanged = coordinates.x1 !== initialCoordinates.x1;
11093
- if (isChanged) {
11094
- switch (action) {
11095
- case "move": {
11096
- changedTask.start = dateByX(
11097
- coordinates.x1,
11098
- initialCoordinates.x1,
11099
- selectedTask.start,
11100
- xStep,
11101
- timeStep
11102
- );
11103
- changedTask.end = changedTask.start;
11104
- break;
11105
- }
11106
- }
11107
- }
11108
- return { isChanged, changedTask };
11109
- };
11110
- const calculateDataDatePosition = ({
11111
- dataDate,
11112
- startDate,
11113
- viewMode,
11114
- columnWidth
11115
- }) => {
11116
- const milestonePosition = taskXCoordinate(
11117
- dataDate,
11118
- startDate,
11119
- viewMode,
11120
- columnWidth
11121
- );
11122
- const milestoneHalfWidth = 6;
11123
- return milestonePosition + milestoneHalfWidth;
11124
- };
11125
10912
  const GanttTodayInner = ({
11126
10913
  additionalLeftSpace,
11127
- distances: { columnWidth },
10914
+ distances: { columnWidth, barCornerRadius },
11128
10915
  ganttFullHeight,
11129
10916
  isUnknownDates,
11130
10917
  rtl,
@@ -11137,7 +10924,8 @@ const GanttTodayInner = ({
11137
10924
  dataDateColor = null,
11138
10925
  todayLabel = "Today",
11139
10926
  dataDateLabel = "Data Date",
11140
- tasks = []
10927
+ taskHeight = 20,
10928
+ taskYOffset = 5
11141
10929
  }) => {
11142
10930
  const todayElement = useMemo(() => {
11143
10931
  if (isUnknownDates || !showTodayLine) {
@@ -11220,52 +11008,72 @@ const GanttTodayInner = ({
11220
11008
  if (!showDataDateLine || !dataDate) {
11221
11009
  return null;
11222
11010
  }
11223
- const tickX = calculateDataDatePosition({
11224
- dataDate,
11225
- startDate,
11226
- viewMode,
11227
- columnWidth,
11228
- tasks,
11229
- rtl
11230
- });
11231
- const x = rtl ? tickX : tickX;
11011
+ const dataIndex = getDatesDiff(dataDate, startDate, viewMode);
11012
+ const extraMultiplier = () => {
11013
+ switch (viewMode) {
11014
+ case ViewMode.Week: {
11015
+ const percent = dataDate.getDay() / 7;
11016
+ return 1 + percent * 0.2;
11017
+ }
11018
+ case ViewMode.Month: {
11019
+ const dayInMonth = dataDate.getDate();
11020
+ const maxDaysInMonth = getDaysInMonth(
11021
+ dataDate.getMonth(),
11022
+ dataDate.getFullYear()
11023
+ );
11024
+ const percent = dayInMonth / maxDaysInMonth;
11025
+ return 1 + percent * 0.5;
11026
+ }
11027
+ case ViewMode.Year: {
11028
+ const percent = dataDate.getMonth() / 12;
11029
+ return 1 + percent * 0.5;
11030
+ }
11031
+ default:
11032
+ return 1;
11033
+ }
11034
+ };
11035
+ const tickX = dataIndex * columnWidth * extraMultiplier();
11036
+ const x = rtl ? tickX + columnWidth : tickX;
11232
11037
  const color = dataDateColor || "var(--gantt-calendar-today-color)";
11038
+ const rotatedHeight = taskHeight / 1.414;
11039
+ const milestoneX = x + additionalLeftSpace - rotatedHeight * 0.5;
11040
+ const milestoneY = taskYOffset;
11041
+ const transform = `rotate(45 ${milestoneX + rotatedHeight * 0.356} ${milestoneY + rotatedHeight * 0.85})`;
11042
+ const milestoneCenterX = milestoneX + rotatedHeight * 0.5;
11043
+ const lineX = milestoneCenterX + rotatedHeight / Math.sqrt(2) * 0.5;
11233
11044
  return /* @__PURE__ */ jsxs(Fragment, { children: [
11234
11045
  /* @__PURE__ */ jsx(
11235
11046
  "rect",
11236
11047
  {
11237
- x: additionalLeftSpace + x,
11238
- y: 0,
11239
- width: 2,
11240
- height: ganttFullHeight,
11048
+ x: milestoneX,
11049
+ y: milestoneY,
11050
+ width: rotatedHeight,
11051
+ height: rotatedHeight,
11052
+ rx: barCornerRadius,
11053
+ ry: barCornerRadius,
11054
+ transform,
11241
11055
  fill: color,
11242
- opacity: 0.9
11243
- }
11244
- ),
11245
- /* @__PURE__ */ jsx(
11246
- "circle",
11247
- {
11248
- className: styles$c.ganttTodayCircle,
11249
- cx: x + 1,
11250
- cy: 6,
11251
- r: 6,
11252
- fill: color
11056
+ opacity: 0.9,
11057
+ stroke: color,
11058
+ strokeWidth: 1
11253
11059
  }
11254
11060
  ),
11255
11061
  /* @__PURE__ */ jsx(
11256
- "text",
11062
+ "rect",
11257
11063
  {
11258
- x: additionalLeftSpace + x + 8,
11259
- y: 10,
11064
+ x: lineX,
11065
+ y: 0,
11066
+ width: 2,
11067
+ height: ganttFullHeight,
11260
11068
  fill: color,
11261
- fontSize: 12,
11262
- fontWeight: 600,
11263
- children: dataDateLabel || "Data Date"
11069
+ opacity: 0.7
11264
11070
  }
11265
- )
11071
+ ),
11072
+ /* @__PURE__ */ jsx("text", { x: lineX + 8, y: 10, fill: color, fontSize: 12, fontWeight: 600, children: dataDateLabel || "Data Date" })
11266
11073
  ] });
11267
11074
  }, [
11268
11075
  additionalLeftSpace,
11076
+ barCornerRadius,
11269
11077
  columnWidth,
11270
11078
  ganttFullHeight,
11271
11079
  rtl,
@@ -11275,7 +11083,8 @@ const GanttTodayInner = ({
11275
11083
  dataDate,
11276
11084
  dataDateColor,
11277
11085
  dataDateLabel,
11278
- tasks
11086
+ taskHeight,
11087
+ taskYOffset
11279
11088
  ]);
11280
11089
  return /* @__PURE__ */ jsxs("g", { className: "today", children: [
11281
11090
  dataDateElement,
@@ -11970,6 +11779,204 @@ const RelationLine = ({
11970
11779
  }
11971
11780
  );
11972
11781
  };
11782
+ const getDateByOffset = (startDate, offset2, viewMode) => {
11783
+ switch (viewMode) {
11784
+ case ViewMode.Day:
11785
+ return addDays(startDate, offset2);
11786
+ case ViewMode.HalfDay:
11787
+ return addHours(startDate, offset2 * 12);
11788
+ case ViewMode.QuarterDay:
11789
+ return addHours(startDate, offset2 * 6);
11790
+ case ViewMode.Hour:
11791
+ return addHours(startDate, offset2);
11792
+ case ViewMode.Month:
11793
+ return addMonths(startDate, offset2);
11794
+ case ViewMode.Week:
11795
+ return addWeeks(startDate, offset2);
11796
+ case ViewMode.Year:
11797
+ return addYears(startDate, offset2);
11798
+ default:
11799
+ throw new Error("Unknown view mode");
11800
+ }
11801
+ };
11802
+ const taskXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
11803
+ const index2 = getDatesDiff(xDate, startDate, viewMode);
11804
+ const currentDate = getDateByOffset(startDate, index2, viewMode);
11805
+ const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
11806
+ const remainderMillis = xDate.getTime() - currentDate.getTime();
11807
+ const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
11808
+ return index2 * columnWidth + percentOfInterval * columnWidth;
11809
+ };
11810
+ const taskComparisonXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
11811
+ const index2 = getDatesDiff(xDate, startDate, viewMode);
11812
+ const currentDate = getDateByOffset(startDate, index2, viewMode);
11813
+ const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
11814
+ const remainderMillis = xDate.getTime() - currentDate.getTime();
11815
+ const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
11816
+ return index2 * columnWidth + percentOfInterval * columnWidth;
11817
+ };
11818
+ const progressWithByParams = (taskX1, taskX2, progress, rtl) => {
11819
+ const progressWidth = Math.max((taskX2 - taskX1) * progress * 0.01, 0);
11820
+ let progressX;
11821
+ if (rtl) {
11822
+ progressX = taskX2 - progressWidth;
11823
+ } else {
11824
+ progressX = taskX1;
11825
+ }
11826
+ return [progressWidth, progressX];
11827
+ };
11828
+ const dateByX = (x, taskX, taskDate, xStep, timeStep) => {
11829
+ let newDate = new Date((x - taskX) / xStep * timeStep + taskDate.getTime());
11830
+ newDate = new Date(
11831
+ newDate.getTime() + (newDate.getTimezoneOffset() - taskDate.getTimezoneOffset()) * 6e4
11832
+ );
11833
+ return newDate;
11834
+ };
11835
+ const handleTaskBySVGMouseEvent = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
11836
+ let result;
11837
+ switch (selectedTask.type) {
11838
+ case "milestone":
11839
+ result = handleTaskBySVGMouseEventForMilestone(
11840
+ action,
11841
+ selectedTask,
11842
+ initialCoordinates,
11843
+ coordinates,
11844
+ xStep,
11845
+ timeStep
11846
+ );
11847
+ break;
11848
+ default:
11849
+ result = handleTaskBySVGMouseEventForBar(
11850
+ action,
11851
+ selectedTask,
11852
+ initialCoordinates,
11853
+ coordinates,
11854
+ xStep,
11855
+ timeStep,
11856
+ rtl
11857
+ );
11858
+ break;
11859
+ }
11860
+ return result;
11861
+ };
11862
+ const handleTaskBySVGMouseEventForBar = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
11863
+ const changedTask = { ...selectedTask };
11864
+ let isChanged = false;
11865
+ switch (action) {
11866
+ case "progress":
11867
+ isChanged = initialCoordinates.progressWidth !== coordinates.progressWidth;
11868
+ if (isChanged) {
11869
+ changedTask.progress = Math.round(
11870
+ coordinates.progressWidth * 100 / (coordinates.x2 - coordinates.x1)
11871
+ );
11872
+ }
11873
+ break;
11874
+ case "start": {
11875
+ isChanged = initialCoordinates.x1 !== coordinates.x1;
11876
+ if (isChanged) {
11877
+ if (rtl) {
11878
+ changedTask.end = dateByX(
11879
+ coordinates.x1,
11880
+ initialCoordinates.x1,
11881
+ selectedTask.end,
11882
+ xStep,
11883
+ timeStep
11884
+ );
11885
+ } else {
11886
+ changedTask.start = dateByX(
11887
+ coordinates.x1,
11888
+ initialCoordinates.x1,
11889
+ selectedTask.start,
11890
+ xStep,
11891
+ timeStep
11892
+ );
11893
+ }
11894
+ }
11895
+ break;
11896
+ }
11897
+ case "end": {
11898
+ isChanged = initialCoordinates.x2 !== coordinates.x2;
11899
+ if (isChanged) {
11900
+ if (rtl) {
11901
+ changedTask.start = dateByX(
11902
+ coordinates.x2,
11903
+ initialCoordinates.x2,
11904
+ selectedTask.start,
11905
+ xStep,
11906
+ timeStep
11907
+ );
11908
+ } else {
11909
+ changedTask.end = dateByX(
11910
+ coordinates.x2,
11911
+ initialCoordinates.x2,
11912
+ selectedTask.end,
11913
+ xStep,
11914
+ timeStep
11915
+ );
11916
+ }
11917
+ }
11918
+ break;
11919
+ }
11920
+ case "move": {
11921
+ isChanged = initialCoordinates.x1 !== coordinates.x1;
11922
+ if (isChanged) {
11923
+ if (rtl) {
11924
+ changedTask.end = dateByX(
11925
+ coordinates.x1,
11926
+ initialCoordinates.x1,
11927
+ selectedTask.end,
11928
+ xStep,
11929
+ timeStep
11930
+ );
11931
+ changedTask.start = dateByX(
11932
+ coordinates.x2,
11933
+ initialCoordinates.x2,
11934
+ selectedTask.start,
11935
+ xStep,
11936
+ timeStep
11937
+ );
11938
+ } else {
11939
+ changedTask.start = dateByX(
11940
+ coordinates.x1,
11941
+ initialCoordinates.x1,
11942
+ selectedTask.start,
11943
+ xStep,
11944
+ timeStep
11945
+ );
11946
+ changedTask.end = dateByX(
11947
+ coordinates.x2,
11948
+ initialCoordinates.x2,
11949
+ selectedTask.end,
11950
+ xStep,
11951
+ timeStep
11952
+ );
11953
+ }
11954
+ }
11955
+ break;
11956
+ }
11957
+ }
11958
+ return { isChanged, changedTask };
11959
+ };
11960
+ const handleTaskBySVGMouseEventForMilestone = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep) => {
11961
+ const changedTask = { ...selectedTask };
11962
+ const isChanged = coordinates.x1 !== initialCoordinates.x1;
11963
+ if (isChanged) {
11964
+ switch (action) {
11965
+ case "move": {
11966
+ changedTask.start = dateByX(
11967
+ coordinates.x1,
11968
+ initialCoordinates.x1,
11969
+ selectedTask.start,
11970
+ xStep,
11971
+ timeStep
11972
+ );
11973
+ changedTask.end = changedTask.start;
11974
+ break;
11975
+ }
11976
+ }
11977
+ }
11978
+ return { isChanged, changedTask };
11979
+ };
11973
11980
  const barWrapper = "_barWrapper_5jhkr_1";
11974
11981
  const barHandle = "_barHandle_5jhkr_11";
11975
11982
  const barHandleImportantVisible = "_barHandleImportantVisible_5jhkr_37";
@@ -20187,7 +20194,8 @@ const Gantt = (props) => {
20187
20194
  dataDateColor,
20188
20195
  todayLabel,
20189
20196
  dataDateLabel,
20190
- tasks: sortedTasks.filter((task) => task.type !== "empty")
20197
+ taskHeight,
20198
+ taskYOffset
20191
20199
  }),
20192
20200
  [
20193
20201
  additionalLeftSpace,
@@ -20204,7 +20212,8 @@ const Gantt = (props) => {
20204
20212
  dataDateColor,
20205
20213
  todayLabel,
20206
20214
  dataDateLabel,
20207
- sortedTasks
20215
+ taskHeight,
20216
+ taskYOffset
20208
20217
  ]
20209
20218
  );
20210
20219
  const calendarProps = useMemo(
@@ -10926,222 +10926,9 @@
10926
10926
  ganttToday,
10927
10927
  ganttTodayCircle
10928
10928
  };
10929
- const getDateByOffset = (startDate, offset2, viewMode) => {
10930
- switch (viewMode) {
10931
- case ViewMode.Day:
10932
- return addDays(startDate, offset2);
10933
- case ViewMode.HalfDay:
10934
- return addHours(startDate, offset2 * 12);
10935
- case ViewMode.QuarterDay:
10936
- return addHours(startDate, offset2 * 6);
10937
- case ViewMode.Hour:
10938
- return addHours(startDate, offset2);
10939
- case ViewMode.Month:
10940
- return addMonths(startDate, offset2);
10941
- case ViewMode.Week:
10942
- return addWeeks(startDate, offset2);
10943
- case ViewMode.Year:
10944
- return addYears(startDate, offset2);
10945
- default:
10946
- throw new Error("Unknown view mode");
10947
- }
10948
- };
10949
- const taskXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
10950
- const index2 = getDatesDiff(xDate, startDate, viewMode);
10951
- const currentDate = getDateByOffset(startDate, index2, viewMode);
10952
- const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
10953
- const remainderMillis = xDate.getTime() - currentDate.getTime();
10954
- const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
10955
- return index2 * columnWidth + percentOfInterval * columnWidth;
10956
- };
10957
- const taskComparisonXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
10958
- const index2 = getDatesDiff(xDate, startDate, viewMode);
10959
- const currentDate = getDateByOffset(startDate, index2, viewMode);
10960
- const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
10961
- const remainderMillis = xDate.getTime() - currentDate.getTime();
10962
- const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
10963
- return index2 * columnWidth + percentOfInterval * columnWidth;
10964
- };
10965
- const progressWithByParams = (taskX1, taskX2, progress, rtl) => {
10966
- const progressWidth = Math.max((taskX2 - taskX1) * progress * 0.01, 0);
10967
- let progressX;
10968
- if (rtl) {
10969
- progressX = taskX2 - progressWidth;
10970
- } else {
10971
- progressX = taskX1;
10972
- }
10973
- return [progressWidth, progressX];
10974
- };
10975
- const dateByX = (x, taskX, taskDate, xStep, timeStep) => {
10976
- let newDate = new Date((x - taskX) / xStep * timeStep + taskDate.getTime());
10977
- newDate = new Date(
10978
- newDate.getTime() + (newDate.getTimezoneOffset() - taskDate.getTimezoneOffset()) * 6e4
10979
- );
10980
- return newDate;
10981
- };
10982
- const handleTaskBySVGMouseEvent = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
10983
- let result;
10984
- switch (selectedTask.type) {
10985
- case "milestone":
10986
- result = handleTaskBySVGMouseEventForMilestone(
10987
- action,
10988
- selectedTask,
10989
- initialCoordinates,
10990
- coordinates,
10991
- xStep,
10992
- timeStep
10993
- );
10994
- break;
10995
- default:
10996
- result = handleTaskBySVGMouseEventForBar(
10997
- action,
10998
- selectedTask,
10999
- initialCoordinates,
11000
- coordinates,
11001
- xStep,
11002
- timeStep,
11003
- rtl
11004
- );
11005
- break;
11006
- }
11007
- return result;
11008
- };
11009
- const handleTaskBySVGMouseEventForBar = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
11010
- const changedTask = { ...selectedTask };
11011
- let isChanged = false;
11012
- switch (action) {
11013
- case "progress":
11014
- isChanged = initialCoordinates.progressWidth !== coordinates.progressWidth;
11015
- if (isChanged) {
11016
- changedTask.progress = Math.round(
11017
- coordinates.progressWidth * 100 / (coordinates.x2 - coordinates.x1)
11018
- );
11019
- }
11020
- break;
11021
- case "start": {
11022
- isChanged = initialCoordinates.x1 !== coordinates.x1;
11023
- if (isChanged) {
11024
- if (rtl) {
11025
- changedTask.end = dateByX(
11026
- coordinates.x1,
11027
- initialCoordinates.x1,
11028
- selectedTask.end,
11029
- xStep,
11030
- timeStep
11031
- );
11032
- } else {
11033
- changedTask.start = dateByX(
11034
- coordinates.x1,
11035
- initialCoordinates.x1,
11036
- selectedTask.start,
11037
- xStep,
11038
- timeStep
11039
- );
11040
- }
11041
- }
11042
- break;
11043
- }
11044
- case "end": {
11045
- isChanged = initialCoordinates.x2 !== coordinates.x2;
11046
- if (isChanged) {
11047
- if (rtl) {
11048
- changedTask.start = dateByX(
11049
- coordinates.x2,
11050
- initialCoordinates.x2,
11051
- selectedTask.start,
11052
- xStep,
11053
- timeStep
11054
- );
11055
- } else {
11056
- changedTask.end = dateByX(
11057
- coordinates.x2,
11058
- initialCoordinates.x2,
11059
- selectedTask.end,
11060
- xStep,
11061
- timeStep
11062
- );
11063
- }
11064
- }
11065
- break;
11066
- }
11067
- case "move": {
11068
- isChanged = initialCoordinates.x1 !== coordinates.x1;
11069
- if (isChanged) {
11070
- if (rtl) {
11071
- changedTask.end = dateByX(
11072
- coordinates.x1,
11073
- initialCoordinates.x1,
11074
- selectedTask.end,
11075
- xStep,
11076
- timeStep
11077
- );
11078
- changedTask.start = dateByX(
11079
- coordinates.x2,
11080
- initialCoordinates.x2,
11081
- selectedTask.start,
11082
- xStep,
11083
- timeStep
11084
- );
11085
- } else {
11086
- changedTask.start = dateByX(
11087
- coordinates.x1,
11088
- initialCoordinates.x1,
11089
- selectedTask.start,
11090
- xStep,
11091
- timeStep
11092
- );
11093
- changedTask.end = dateByX(
11094
- coordinates.x2,
11095
- initialCoordinates.x2,
11096
- selectedTask.end,
11097
- xStep,
11098
- timeStep
11099
- );
11100
- }
11101
- }
11102
- break;
11103
- }
11104
- }
11105
- return { isChanged, changedTask };
11106
- };
11107
- const handleTaskBySVGMouseEventForMilestone = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep) => {
11108
- const changedTask = { ...selectedTask };
11109
- const isChanged = coordinates.x1 !== initialCoordinates.x1;
11110
- if (isChanged) {
11111
- switch (action) {
11112
- case "move": {
11113
- changedTask.start = dateByX(
11114
- coordinates.x1,
11115
- initialCoordinates.x1,
11116
- selectedTask.start,
11117
- xStep,
11118
- timeStep
11119
- );
11120
- changedTask.end = changedTask.start;
11121
- break;
11122
- }
11123
- }
11124
- }
11125
- return { isChanged, changedTask };
11126
- };
11127
- const calculateDataDatePosition = ({
11128
- dataDate,
11129
- startDate,
11130
- viewMode,
11131
- columnWidth
11132
- }) => {
11133
- const milestonePosition = taskXCoordinate(
11134
- dataDate,
11135
- startDate,
11136
- viewMode,
11137
- columnWidth
11138
- );
11139
- const milestoneHalfWidth = 6;
11140
- return milestonePosition + milestoneHalfWidth;
11141
- };
11142
10929
  const GanttTodayInner = ({
11143
10930
  additionalLeftSpace,
11144
- distances: { columnWidth },
10931
+ distances: { columnWidth, barCornerRadius },
11145
10932
  ganttFullHeight,
11146
10933
  isUnknownDates,
11147
10934
  rtl,
@@ -11154,7 +10941,8 @@
11154
10941
  dataDateColor = null,
11155
10942
  todayLabel = "Today",
11156
10943
  dataDateLabel = "Data Date",
11157
- tasks = []
10944
+ taskHeight = 20,
10945
+ taskYOffset = 5
11158
10946
  }) => {
11159
10947
  const todayElement = React.useMemo(() => {
11160
10948
  if (isUnknownDates || !showTodayLine) {
@@ -11237,52 +11025,72 @@
11237
11025
  if (!showDataDateLine || !dataDate) {
11238
11026
  return null;
11239
11027
  }
11240
- const tickX = calculateDataDatePosition({
11241
- dataDate,
11242
- startDate,
11243
- viewMode,
11244
- columnWidth,
11245
- tasks,
11246
- rtl
11247
- });
11248
- const x = rtl ? tickX : tickX;
11028
+ const dataIndex = getDatesDiff(dataDate, startDate, viewMode);
11029
+ const extraMultiplier = () => {
11030
+ switch (viewMode) {
11031
+ case ViewMode.Week: {
11032
+ const percent = dataDate.getDay() / 7;
11033
+ return 1 + percent * 0.2;
11034
+ }
11035
+ case ViewMode.Month: {
11036
+ const dayInMonth = dataDate.getDate();
11037
+ const maxDaysInMonth = getDaysInMonth(
11038
+ dataDate.getMonth(),
11039
+ dataDate.getFullYear()
11040
+ );
11041
+ const percent = dayInMonth / maxDaysInMonth;
11042
+ return 1 + percent * 0.5;
11043
+ }
11044
+ case ViewMode.Year: {
11045
+ const percent = dataDate.getMonth() / 12;
11046
+ return 1 + percent * 0.5;
11047
+ }
11048
+ default:
11049
+ return 1;
11050
+ }
11051
+ };
11052
+ const tickX = dataIndex * columnWidth * extraMultiplier();
11053
+ const x = rtl ? tickX + columnWidth : tickX;
11249
11054
  const color = dataDateColor || "var(--gantt-calendar-today-color)";
11055
+ const rotatedHeight = taskHeight / 1.414;
11056
+ const milestoneX = x + additionalLeftSpace - rotatedHeight * 0.5;
11057
+ const milestoneY = taskYOffset;
11058
+ const transform = `rotate(45 ${milestoneX + rotatedHeight * 0.356} ${milestoneY + rotatedHeight * 0.85})`;
11059
+ const milestoneCenterX = milestoneX + rotatedHeight * 0.5;
11060
+ const lineX = milestoneCenterX + rotatedHeight / Math.sqrt(2) * 0.5;
11250
11061
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11251
11062
  /* @__PURE__ */ jsxRuntime.jsx(
11252
11063
  "rect",
11253
11064
  {
11254
- x: additionalLeftSpace + x,
11255
- y: 0,
11256
- width: 2,
11257
- height: ganttFullHeight,
11065
+ x: milestoneX,
11066
+ y: milestoneY,
11067
+ width: rotatedHeight,
11068
+ height: rotatedHeight,
11069
+ rx: barCornerRadius,
11070
+ ry: barCornerRadius,
11071
+ transform,
11258
11072
  fill: color,
11259
- opacity: 0.9
11260
- }
11261
- ),
11262
- /* @__PURE__ */ jsxRuntime.jsx(
11263
- "circle",
11264
- {
11265
- className: styles$c.ganttTodayCircle,
11266
- cx: x + 1,
11267
- cy: 6,
11268
- r: 6,
11269
- fill: color
11073
+ opacity: 0.9,
11074
+ stroke: color,
11075
+ strokeWidth: 1
11270
11076
  }
11271
11077
  ),
11272
11078
  /* @__PURE__ */ jsxRuntime.jsx(
11273
- "text",
11079
+ "rect",
11274
11080
  {
11275
- x: additionalLeftSpace + x + 8,
11276
- y: 10,
11081
+ x: lineX,
11082
+ y: 0,
11083
+ width: 2,
11084
+ height: ganttFullHeight,
11277
11085
  fill: color,
11278
- fontSize: 12,
11279
- fontWeight: 600,
11280
- children: dataDateLabel || "Data Date"
11086
+ opacity: 0.7
11281
11087
  }
11282
- )
11088
+ ),
11089
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: lineX + 8, y: 10, fill: color, fontSize: 12, fontWeight: 600, children: dataDateLabel || "Data Date" })
11283
11090
  ] });
11284
11091
  }, [
11285
11092
  additionalLeftSpace,
11093
+ barCornerRadius,
11286
11094
  columnWidth,
11287
11095
  ganttFullHeight,
11288
11096
  rtl,
@@ -11292,7 +11100,8 @@
11292
11100
  dataDate,
11293
11101
  dataDateColor,
11294
11102
  dataDateLabel,
11295
- tasks
11103
+ taskHeight,
11104
+ taskYOffset
11296
11105
  ]);
11297
11106
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { className: "today", children: [
11298
11107
  dataDateElement,
@@ -11987,6 +11796,204 @@
11987
11796
  }
11988
11797
  );
11989
11798
  };
11799
+ const getDateByOffset = (startDate, offset2, viewMode) => {
11800
+ switch (viewMode) {
11801
+ case ViewMode.Day:
11802
+ return addDays(startDate, offset2);
11803
+ case ViewMode.HalfDay:
11804
+ return addHours(startDate, offset2 * 12);
11805
+ case ViewMode.QuarterDay:
11806
+ return addHours(startDate, offset2 * 6);
11807
+ case ViewMode.Hour:
11808
+ return addHours(startDate, offset2);
11809
+ case ViewMode.Month:
11810
+ return addMonths(startDate, offset2);
11811
+ case ViewMode.Week:
11812
+ return addWeeks(startDate, offset2);
11813
+ case ViewMode.Year:
11814
+ return addYears(startDate, offset2);
11815
+ default:
11816
+ throw new Error("Unknown view mode");
11817
+ }
11818
+ };
11819
+ const taskXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
11820
+ const index2 = getDatesDiff(xDate, startDate, viewMode);
11821
+ const currentDate = getDateByOffset(startDate, index2, viewMode);
11822
+ const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
11823
+ const remainderMillis = xDate.getTime() - currentDate.getTime();
11824
+ const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
11825
+ return index2 * columnWidth + percentOfInterval * columnWidth;
11826
+ };
11827
+ const taskComparisonXCoordinate = (xDate, startDate, viewMode, columnWidth) => {
11828
+ const index2 = getDatesDiff(xDate, startDate, viewMode);
11829
+ const currentDate = getDateByOffset(startDate, index2, viewMode);
11830
+ const nextDate = getDateByOffset(startDate, index2 + 1, viewMode);
11831
+ const remainderMillis = xDate.getTime() - currentDate.getTime();
11832
+ const percentOfInterval = remainderMillis / (nextDate.getTime() - currentDate.getTime());
11833
+ return index2 * columnWidth + percentOfInterval * columnWidth;
11834
+ };
11835
+ const progressWithByParams = (taskX1, taskX2, progress, rtl) => {
11836
+ const progressWidth = Math.max((taskX2 - taskX1) * progress * 0.01, 0);
11837
+ let progressX;
11838
+ if (rtl) {
11839
+ progressX = taskX2 - progressWidth;
11840
+ } else {
11841
+ progressX = taskX1;
11842
+ }
11843
+ return [progressWidth, progressX];
11844
+ };
11845
+ const dateByX = (x, taskX, taskDate, xStep, timeStep) => {
11846
+ let newDate = new Date((x - taskX) / xStep * timeStep + taskDate.getTime());
11847
+ newDate = new Date(
11848
+ newDate.getTime() + (newDate.getTimezoneOffset() - taskDate.getTimezoneOffset()) * 6e4
11849
+ );
11850
+ return newDate;
11851
+ };
11852
+ const handleTaskBySVGMouseEvent = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
11853
+ let result;
11854
+ switch (selectedTask.type) {
11855
+ case "milestone":
11856
+ result = handleTaskBySVGMouseEventForMilestone(
11857
+ action,
11858
+ selectedTask,
11859
+ initialCoordinates,
11860
+ coordinates,
11861
+ xStep,
11862
+ timeStep
11863
+ );
11864
+ break;
11865
+ default:
11866
+ result = handleTaskBySVGMouseEventForBar(
11867
+ action,
11868
+ selectedTask,
11869
+ initialCoordinates,
11870
+ coordinates,
11871
+ xStep,
11872
+ timeStep,
11873
+ rtl
11874
+ );
11875
+ break;
11876
+ }
11877
+ return result;
11878
+ };
11879
+ const handleTaskBySVGMouseEventForBar = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep, rtl) => {
11880
+ const changedTask = { ...selectedTask };
11881
+ let isChanged = false;
11882
+ switch (action) {
11883
+ case "progress":
11884
+ isChanged = initialCoordinates.progressWidth !== coordinates.progressWidth;
11885
+ if (isChanged) {
11886
+ changedTask.progress = Math.round(
11887
+ coordinates.progressWidth * 100 / (coordinates.x2 - coordinates.x1)
11888
+ );
11889
+ }
11890
+ break;
11891
+ case "start": {
11892
+ isChanged = initialCoordinates.x1 !== coordinates.x1;
11893
+ if (isChanged) {
11894
+ if (rtl) {
11895
+ changedTask.end = dateByX(
11896
+ coordinates.x1,
11897
+ initialCoordinates.x1,
11898
+ selectedTask.end,
11899
+ xStep,
11900
+ timeStep
11901
+ );
11902
+ } else {
11903
+ changedTask.start = dateByX(
11904
+ coordinates.x1,
11905
+ initialCoordinates.x1,
11906
+ selectedTask.start,
11907
+ xStep,
11908
+ timeStep
11909
+ );
11910
+ }
11911
+ }
11912
+ break;
11913
+ }
11914
+ case "end": {
11915
+ isChanged = initialCoordinates.x2 !== coordinates.x2;
11916
+ if (isChanged) {
11917
+ if (rtl) {
11918
+ changedTask.start = dateByX(
11919
+ coordinates.x2,
11920
+ initialCoordinates.x2,
11921
+ selectedTask.start,
11922
+ xStep,
11923
+ timeStep
11924
+ );
11925
+ } else {
11926
+ changedTask.end = dateByX(
11927
+ coordinates.x2,
11928
+ initialCoordinates.x2,
11929
+ selectedTask.end,
11930
+ xStep,
11931
+ timeStep
11932
+ );
11933
+ }
11934
+ }
11935
+ break;
11936
+ }
11937
+ case "move": {
11938
+ isChanged = initialCoordinates.x1 !== coordinates.x1;
11939
+ if (isChanged) {
11940
+ if (rtl) {
11941
+ changedTask.end = dateByX(
11942
+ coordinates.x1,
11943
+ initialCoordinates.x1,
11944
+ selectedTask.end,
11945
+ xStep,
11946
+ timeStep
11947
+ );
11948
+ changedTask.start = dateByX(
11949
+ coordinates.x2,
11950
+ initialCoordinates.x2,
11951
+ selectedTask.start,
11952
+ xStep,
11953
+ timeStep
11954
+ );
11955
+ } else {
11956
+ changedTask.start = dateByX(
11957
+ coordinates.x1,
11958
+ initialCoordinates.x1,
11959
+ selectedTask.start,
11960
+ xStep,
11961
+ timeStep
11962
+ );
11963
+ changedTask.end = dateByX(
11964
+ coordinates.x2,
11965
+ initialCoordinates.x2,
11966
+ selectedTask.end,
11967
+ xStep,
11968
+ timeStep
11969
+ );
11970
+ }
11971
+ }
11972
+ break;
11973
+ }
11974
+ }
11975
+ return { isChanged, changedTask };
11976
+ };
11977
+ const handleTaskBySVGMouseEventForMilestone = (action, selectedTask, initialCoordinates, coordinates, xStep, timeStep) => {
11978
+ const changedTask = { ...selectedTask };
11979
+ const isChanged = coordinates.x1 !== initialCoordinates.x1;
11980
+ if (isChanged) {
11981
+ switch (action) {
11982
+ case "move": {
11983
+ changedTask.start = dateByX(
11984
+ coordinates.x1,
11985
+ initialCoordinates.x1,
11986
+ selectedTask.start,
11987
+ xStep,
11988
+ timeStep
11989
+ );
11990
+ changedTask.end = changedTask.start;
11991
+ break;
11992
+ }
11993
+ }
11994
+ }
11995
+ return { isChanged, changedTask };
11996
+ };
11990
11997
  const barWrapper = "_barWrapper_5jhkr_1";
11991
11998
  const barHandle = "_barHandle_5jhkr_11";
11992
11999
  const barHandleImportantVisible = "_barHandleImportantVisible_5jhkr_37";
@@ -20204,7 +20211,8 @@
20204
20211
  dataDateColor,
20205
20212
  todayLabel,
20206
20213
  dataDateLabel,
20207
- tasks: sortedTasks.filter((task) => task.type !== "empty")
20214
+ taskHeight,
20215
+ taskYOffset
20208
20216
  }),
20209
20217
  [
20210
20218
  additionalLeftSpace,
@@ -20221,7 +20229,8 @@
20221
20229
  dataDateColor,
20222
20230
  todayLabel,
20223
20231
  dataDateLabel,
20224
- sortedTasks
20232
+ taskHeight,
20233
+ taskYOffset
20225
20234
  ]
20226
20235
  );
20227
20236
  const calendarProps = React.useMemo(
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "gantt-task-react-v",
3
- "version": "1.2.10",
3
+ "version": "1.2.12",
4
4
  "description": "Interactive Gantt Chart for React with TypeScript.",
5
5
  "author": "aguilanbon",
6
6
  "homepage": "https://github.com/aguilanbon/gantt-task-react-v",
@@ -1,14 +0,0 @@
1
- import { Task, ViewMode } from "../types";
2
- export interface DataDatePositionOptions {
3
- dataDate: Date;
4
- startDate: Date;
5
- viewMode: ViewMode;
6
- columnWidth: number;
7
- tasks?: readonly Task[];
8
- rtl?: boolean;
9
- }
10
- /**
11
- * Calculate data date line position by creating a virtual milestone bar for the data date
12
- * and positioning the line at the end of that milestone bar (just like the custom frontend fix)
13
- */
14
- export declare const calculateDataDatePosition: ({ dataDate, startDate, viewMode, columnWidth, }: DataDatePositionOptions) => number;