gantt-task-react-v 1.2.11 → 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,223 +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 milestoneCenter = taskXCoordinate(
11117
- dataDate,
11118
- startDate,
11119
- viewMode,
11120
- columnWidth
11121
- );
11122
- const taskHeight = 32;
11123
- const milestoneRightEdge = milestoneCenter + taskHeight * 0.5;
11124
- return milestoneRightEdge;
11125
- };
11126
10912
  const GanttTodayInner = ({
11127
10913
  additionalLeftSpace,
11128
- distances: { columnWidth },
10914
+ distances: { columnWidth, barCornerRadius },
11129
10915
  ganttFullHeight,
11130
10916
  isUnknownDates,
11131
10917
  rtl,
@@ -11138,7 +10924,8 @@ const GanttTodayInner = ({
11138
10924
  dataDateColor = null,
11139
10925
  todayLabel = "Today",
11140
10926
  dataDateLabel = "Data Date",
11141
- tasks = []
10927
+ taskHeight = 20,
10928
+ taskYOffset = 5
11142
10929
  }) => {
11143
10930
  const todayElement = useMemo(() => {
11144
10931
  if (isUnknownDates || !showTodayLine) {
@@ -11221,52 +11008,72 @@ const GanttTodayInner = ({
11221
11008
  if (!showDataDateLine || !dataDate) {
11222
11009
  return null;
11223
11010
  }
11224
- const tickX = calculateDataDatePosition({
11225
- dataDate,
11226
- startDate,
11227
- viewMode,
11228
- columnWidth,
11229
- tasks,
11230
- rtl
11231
- });
11232
- 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;
11233
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;
11234
11044
  return /* @__PURE__ */ jsxs(Fragment, { children: [
11235
11045
  /* @__PURE__ */ jsx(
11236
11046
  "rect",
11237
11047
  {
11238
- x: additionalLeftSpace + x,
11239
- y: 0,
11240
- width: 2,
11241
- height: ganttFullHeight,
11048
+ x: milestoneX,
11049
+ y: milestoneY,
11050
+ width: rotatedHeight,
11051
+ height: rotatedHeight,
11052
+ rx: barCornerRadius,
11053
+ ry: barCornerRadius,
11054
+ transform,
11242
11055
  fill: color,
11243
- opacity: 0.9
11244
- }
11245
- ),
11246
- /* @__PURE__ */ jsx(
11247
- "circle",
11248
- {
11249
- className: styles$c.ganttTodayCircle,
11250
- cx: x + 1,
11251
- cy: 6,
11252
- r: 6,
11253
- fill: color
11056
+ opacity: 0.9,
11057
+ stroke: color,
11058
+ strokeWidth: 1
11254
11059
  }
11255
11060
  ),
11256
11061
  /* @__PURE__ */ jsx(
11257
- "text",
11062
+ "rect",
11258
11063
  {
11259
- x: additionalLeftSpace + x + 8,
11260
- y: 10,
11064
+ x: lineX,
11065
+ y: 0,
11066
+ width: 2,
11067
+ height: ganttFullHeight,
11261
11068
  fill: color,
11262
- fontSize: 12,
11263
- fontWeight: 600,
11264
- children: dataDateLabel || "Data Date"
11069
+ opacity: 0.7
11265
11070
  }
11266
- )
11071
+ ),
11072
+ /* @__PURE__ */ jsx("text", { x: lineX + 8, y: 10, fill: color, fontSize: 12, fontWeight: 600, children: dataDateLabel || "Data Date" })
11267
11073
  ] });
11268
11074
  }, [
11269
11075
  additionalLeftSpace,
11076
+ barCornerRadius,
11270
11077
  columnWidth,
11271
11078
  ganttFullHeight,
11272
11079
  rtl,
@@ -11276,7 +11083,8 @@ const GanttTodayInner = ({
11276
11083
  dataDate,
11277
11084
  dataDateColor,
11278
11085
  dataDateLabel,
11279
- tasks
11086
+ taskHeight,
11087
+ taskYOffset
11280
11088
  ]);
11281
11089
  return /* @__PURE__ */ jsxs("g", { className: "today", children: [
11282
11090
  dataDateElement,
@@ -11971,6 +11779,204 @@ const RelationLine = ({
11971
11779
  }
11972
11780
  );
11973
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
+ };
11974
11980
  const barWrapper = "_barWrapper_5jhkr_1";
11975
11981
  const barHandle = "_barHandle_5jhkr_11";
11976
11982
  const barHandleImportantVisible = "_barHandleImportantVisible_5jhkr_37";
@@ -20188,7 +20194,8 @@ const Gantt = (props) => {
20188
20194
  dataDateColor,
20189
20195
  todayLabel,
20190
20196
  dataDateLabel,
20191
- tasks: sortedTasks.filter((task) => task.type !== "empty")
20197
+ taskHeight,
20198
+ taskYOffset
20192
20199
  }),
20193
20200
  [
20194
20201
  additionalLeftSpace,
@@ -20205,7 +20212,8 @@ const Gantt = (props) => {
20205
20212
  dataDateColor,
20206
20213
  todayLabel,
20207
20214
  dataDateLabel,
20208
- sortedTasks
20215
+ taskHeight,
20216
+ taskYOffset
20209
20217
  ]
20210
20218
  );
20211
20219
  const calendarProps = useMemo(
@@ -10926,223 +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 milestoneCenter = taskXCoordinate(
11134
- dataDate,
11135
- startDate,
11136
- viewMode,
11137
- columnWidth
11138
- );
11139
- const taskHeight = 32;
11140
- const milestoneRightEdge = milestoneCenter + taskHeight * 0.5;
11141
- return milestoneRightEdge;
11142
- };
11143
10929
  const GanttTodayInner = ({
11144
10930
  additionalLeftSpace,
11145
- distances: { columnWidth },
10931
+ distances: { columnWidth, barCornerRadius },
11146
10932
  ganttFullHeight,
11147
10933
  isUnknownDates,
11148
10934
  rtl,
@@ -11155,7 +10941,8 @@
11155
10941
  dataDateColor = null,
11156
10942
  todayLabel = "Today",
11157
10943
  dataDateLabel = "Data Date",
11158
- tasks = []
10944
+ taskHeight = 20,
10945
+ taskYOffset = 5
11159
10946
  }) => {
11160
10947
  const todayElement = React.useMemo(() => {
11161
10948
  if (isUnknownDates || !showTodayLine) {
@@ -11238,52 +11025,72 @@
11238
11025
  if (!showDataDateLine || !dataDate) {
11239
11026
  return null;
11240
11027
  }
11241
- const tickX = calculateDataDatePosition({
11242
- dataDate,
11243
- startDate,
11244
- viewMode,
11245
- columnWidth,
11246
- tasks,
11247
- rtl
11248
- });
11249
- 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;
11250
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;
11251
11061
  return /* @__PURE__ */ jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [
11252
11062
  /* @__PURE__ */ jsxRuntime.jsx(
11253
11063
  "rect",
11254
11064
  {
11255
- x: additionalLeftSpace + x,
11256
- y: 0,
11257
- width: 2,
11258
- height: ganttFullHeight,
11065
+ x: milestoneX,
11066
+ y: milestoneY,
11067
+ width: rotatedHeight,
11068
+ height: rotatedHeight,
11069
+ rx: barCornerRadius,
11070
+ ry: barCornerRadius,
11071
+ transform,
11259
11072
  fill: color,
11260
- opacity: 0.9
11261
- }
11262
- ),
11263
- /* @__PURE__ */ jsxRuntime.jsx(
11264
- "circle",
11265
- {
11266
- className: styles$c.ganttTodayCircle,
11267
- cx: x + 1,
11268
- cy: 6,
11269
- r: 6,
11270
- fill: color
11073
+ opacity: 0.9,
11074
+ stroke: color,
11075
+ strokeWidth: 1
11271
11076
  }
11272
11077
  ),
11273
11078
  /* @__PURE__ */ jsxRuntime.jsx(
11274
- "text",
11079
+ "rect",
11275
11080
  {
11276
- x: additionalLeftSpace + x + 8,
11277
- y: 10,
11081
+ x: lineX,
11082
+ y: 0,
11083
+ width: 2,
11084
+ height: ganttFullHeight,
11278
11085
  fill: color,
11279
- fontSize: 12,
11280
- fontWeight: 600,
11281
- children: dataDateLabel || "Data Date"
11086
+ opacity: 0.7
11282
11087
  }
11283
- )
11088
+ ),
11089
+ /* @__PURE__ */ jsxRuntime.jsx("text", { x: lineX + 8, y: 10, fill: color, fontSize: 12, fontWeight: 600, children: dataDateLabel || "Data Date" })
11284
11090
  ] });
11285
11091
  }, [
11286
11092
  additionalLeftSpace,
11093
+ barCornerRadius,
11287
11094
  columnWidth,
11288
11095
  ganttFullHeight,
11289
11096
  rtl,
@@ -11293,7 +11100,8 @@
11293
11100
  dataDate,
11294
11101
  dataDateColor,
11295
11102
  dataDateLabel,
11296
- tasks
11103
+ taskHeight,
11104
+ taskYOffset
11297
11105
  ]);
11298
11106
  return /* @__PURE__ */ jsxRuntime.jsxs("g", { className: "today", children: [
11299
11107
  dataDateElement,
@@ -11988,6 +11796,204 @@
11988
11796
  }
11989
11797
  );
11990
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
+ };
11991
11997
  const barWrapper = "_barWrapper_5jhkr_1";
11992
11998
  const barHandle = "_barHandle_5jhkr_11";
11993
11999
  const barHandleImportantVisible = "_barHandleImportantVisible_5jhkr_37";
@@ -20205,7 +20211,8 @@
20205
20211
  dataDateColor,
20206
20212
  todayLabel,
20207
20213
  dataDateLabel,
20208
- tasks: sortedTasks.filter((task) => task.type !== "empty")
20214
+ taskHeight,
20215
+ taskYOffset
20209
20216
  }),
20210
20217
  [
20211
20218
  additionalLeftSpace,
@@ -20222,7 +20229,8 @@
20222
20229
  dataDateColor,
20223
20230
  todayLabel,
20224
20231
  dataDateLabel,
20225
- sortedTasks
20232
+ taskHeight,
20233
+ taskYOffset
20226
20234
  ]
20227
20235
  );
20228
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.11",
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,18 +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
- /**
15
- * Calculate data date line position by positioning it at the right edge of where a milestone
16
- * would be positioned (exactly matching the actual milestone positioning logic)
17
- */
18
- export declare const calculateDataDatePosition: ({ dataDate, startDate, viewMode, columnWidth, }: DataDatePositionOptions) => number;