datastake-daf 0.6.838 → 0.6.839
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/index.js +1671 -1541
- package/dist/pages/index.js +67 -27
- package/package.json +1 -1
- package/src/@daf/hooks/useTimeFilter.js +1 -1
- package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CommunityParticipation/JobsTimeline/index.jsx +7 -15
- package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleOutcomes/PlantingActivitiesTimeline.jsx +6 -0
- package/src/@daf/pages/Summary/Activities/PlantingCycle/components/CycleOutcomes/RestoredArea.jsx +1 -0
- package/src/@daf/utils/timeFilterUtils.js +43 -14
package/dist/pages/index.js
CHANGED
|
@@ -55693,7 +55693,7 @@ const PlantingLocations = ({
|
|
|
55693
55693
|
* Formats a date based on the time filter
|
|
55694
55694
|
* @param {dayjs.Dayjs} date - The date to format
|
|
55695
55695
|
* @param {boolean} breakLine - Whether to add a line break (for tooltips)
|
|
55696
|
-
* @param {string} timeFilter - The time filter ('daily', 'weekly', 'monthly')
|
|
55696
|
+
* @param {string} timeFilter - The time filter ('daily', 'weekly', 'monthly', 'yearly')
|
|
55697
55697
|
* @returns {string} Formatted date string
|
|
55698
55698
|
*/
|
|
55699
55699
|
const getFormatDate = (date, breakLine = false, timeFilter = 'monthly') => {
|
|
@@ -55702,20 +55702,30 @@ const getFormatDate = (date, breakLine = false, timeFilter = 'monthly') => {
|
|
|
55702
55702
|
return date.format("DD/MM");
|
|
55703
55703
|
case "weekly":
|
|
55704
55704
|
return `W${renderNumber$1(date.week())}`;
|
|
55705
|
+
case "yearly":
|
|
55706
|
+
return date.format("YYYY");
|
|
55705
55707
|
default:
|
|
55706
55708
|
// Monthly format: "Dec 24", "Jan 25", etc.
|
|
55707
|
-
|
|
55708
55709
|
return breakLine ? `${capitalize(date.format("MMM"))}\n${date.format("YY")}` : `${capitalize(date.format("MMM"))} ${date.format("YY")}`;
|
|
55709
55710
|
}
|
|
55710
55711
|
};
|
|
55711
55712
|
|
|
55712
55713
|
/**
|
|
55713
55714
|
* Gets the time quantity string for dayjs operations
|
|
55714
|
-
* @param {string} timeFilter - The time filter ('daily', 'weekly', 'monthly')
|
|
55715
|
-
* @returns {string} Time quantity string ('days', 'weeks', 'months')
|
|
55715
|
+
* @param {string} timeFilter - The time filter ('daily', 'weekly', 'monthly', 'yearly')
|
|
55716
|
+
* @returns {string} Time quantity string ('days', 'weeks', 'months', 'years')
|
|
55716
55717
|
*/
|
|
55717
55718
|
const getTimeQuantity = (timeFilter = 'monthly') => {
|
|
55718
|
-
|
|
55719
|
+
switch (timeFilter) {
|
|
55720
|
+
case "daily":
|
|
55721
|
+
return "days";
|
|
55722
|
+
case "weekly":
|
|
55723
|
+
return "weeks";
|
|
55724
|
+
case "yearly":
|
|
55725
|
+
return "years";
|
|
55726
|
+
default:
|
|
55727
|
+
return "months";
|
|
55728
|
+
}
|
|
55719
55729
|
};
|
|
55720
55730
|
|
|
55721
55731
|
/**
|
|
@@ -55741,6 +55751,9 @@ const getPreviousGraphData = (dates, startDate, timeFilter, valueField = 'total'
|
|
|
55741
55751
|
case "weekly":
|
|
55742
55752
|
isBeforeStart = date.isBefore(startDate, 'week');
|
|
55743
55753
|
break;
|
|
55754
|
+
case "yearly":
|
|
55755
|
+
isBeforeStart = date.isBefore(startDate, 'year');
|
|
55756
|
+
break;
|
|
55744
55757
|
default:
|
|
55745
55758
|
isBeforeStart = date.isBefore(startDate, 'month');
|
|
55746
55759
|
break;
|
|
@@ -55763,7 +55776,7 @@ const getPreviousGraphData = (dates, startDate, timeFilter, valueField = 'total'
|
|
|
55763
55776
|
* Processes chart data with time filtering support
|
|
55764
55777
|
* @param {Object} params - Parameters object
|
|
55765
55778
|
* @param {Array} params.mainData - Array of data objects with date and value fields
|
|
55766
|
-
* @param {string} params.timeFilter - Time filter ('daily', 'weekly', 'monthly')
|
|
55779
|
+
* @param {string} params.timeFilter - Time filter ('daily', 'weekly', 'monthly', 'yearly')
|
|
55767
55780
|
* @param {Object} params.filters - Optional filters object with timeframe
|
|
55768
55781
|
* @param {boolean} params.isCumulative - Whether to calculate cumulative values (default: false)
|
|
55769
55782
|
* @param {string} params.valueField - Field name to extract value from (default: 'total', also checks 'count', 'jobs', 'value')
|
|
@@ -55790,6 +55803,9 @@ const processChartDateData = ({
|
|
|
55790
55803
|
} else if (filter === "weekly") {
|
|
55791
55804
|
start = start.startOf('week');
|
|
55792
55805
|
end = end.startOf('week');
|
|
55806
|
+
} else if (filter === "yearly") {
|
|
55807
|
+
start = start.startOf('year');
|
|
55808
|
+
end = end.startOf('year');
|
|
55793
55809
|
} else {
|
|
55794
55810
|
start = start.startOf('month');
|
|
55795
55811
|
end = end.startOf('month');
|
|
@@ -55806,9 +55822,24 @@ const processChartDateData = ({
|
|
|
55806
55822
|
cumulativeScore = hasPreviousData ? previousCumulativeScore : 0;
|
|
55807
55823
|
}
|
|
55808
55824
|
|
|
55825
|
+
// Get the period unit for comparison
|
|
55826
|
+
const getPeriodUnit = f => {
|
|
55827
|
+
switch (f) {
|
|
55828
|
+
case "daily":
|
|
55829
|
+
return "day";
|
|
55830
|
+
case "weekly":
|
|
55831
|
+
return "week";
|
|
55832
|
+
case "yearly":
|
|
55833
|
+
return "year";
|
|
55834
|
+
default:
|
|
55835
|
+
return "month";
|
|
55836
|
+
}
|
|
55837
|
+
};
|
|
55838
|
+
const periodUnit = getPeriodUnit(filter);
|
|
55839
|
+
|
|
55809
55840
|
// Loop until we reach the end date
|
|
55810
55841
|
let currentDate = start.clone();
|
|
55811
|
-
while (currentDate.isBefore(end) || currentDate.isSame(end,
|
|
55842
|
+
while (currentDate.isBefore(end) || currentDate.isSame(end, periodUnit)) {
|
|
55812
55843
|
// Filter data points that fall within this period
|
|
55813
55844
|
const score = isEmpty ? 0 : dates.filter(d => {
|
|
55814
55845
|
if (!d.date) return false;
|
|
@@ -55817,6 +55848,8 @@ const processChartDateData = ({
|
|
|
55817
55848
|
return d.date === currentDate.format("YYYY-MM-DD");
|
|
55818
55849
|
case "weekly":
|
|
55819
55850
|
return dayjs__default["default"](d.date, "YYYY-MM-DD").week() === currentDate.week() && dayjs__default["default"](d.date, "YYYY-MM-DD").year() === currentDate.year();
|
|
55851
|
+
case "yearly":
|
|
55852
|
+
return dayjs__default["default"](d.date, "YYYY-MM-DD").year() === currentDate.year();
|
|
55820
55853
|
default:
|
|
55821
55854
|
return dayjs__default["default"](d.date, "YYYY-MM-DD").format("YYYY-MM") === currentDate.format("YYYY-MM");
|
|
55822
55855
|
}
|
|
@@ -55853,7 +55886,7 @@ const processChartDateData = ({
|
|
|
55853
55886
|
const formatDateAxis = (label, getFormatDateFn) => {
|
|
55854
55887
|
if (!label) return label;
|
|
55855
55888
|
|
|
55856
|
-
// Check if label is already in the correct format (MMM YY, DD/MM, or
|
|
55889
|
+
// Check if label is already in the correct format (MMM YY, DD/MM, W#, or YYYY)
|
|
55857
55890
|
// If it matches our format patterns, return as-is
|
|
55858
55891
|
if (typeof label === 'string') {
|
|
55859
55892
|
// Check for MMM YY format (e.g., "Dec 24", "Jan 25")
|
|
@@ -55868,6 +55901,10 @@ const formatDateAxis = (label, getFormatDateFn) => {
|
|
|
55868
55901
|
if (/^W\d+$/.test(label)) {
|
|
55869
55902
|
return label;
|
|
55870
55903
|
}
|
|
55904
|
+
// Check for YYYY format (e.g., "2024", "2025")
|
|
55905
|
+
if (/^\d{4}$/.test(label)) {
|
|
55906
|
+
return label;
|
|
55907
|
+
}
|
|
55871
55908
|
}
|
|
55872
55909
|
|
|
55873
55910
|
// Otherwise, try to parse and format it
|
|
@@ -55875,7 +55912,7 @@ const formatDateAxis = (label, getFormatDateFn) => {
|
|
|
55875
55912
|
|
|
55876
55913
|
// If first attempt fails, try parsing as ISO date string
|
|
55877
55914
|
if (!date.isValid() && typeof label === 'string') {
|
|
55878
|
-
date = dayjs__default["default"](label, ['YYYY-MM-DD', 'YYYY-MM', 'MMM YY', 'MMM YYYY', 'DD/MM'], true);
|
|
55915
|
+
date = dayjs__default["default"](label, ['YYYY-MM-DD', 'YYYY-MM', 'YYYY', 'MMM YY', 'MMM YYYY', 'DD/MM'], true);
|
|
55879
55916
|
}
|
|
55880
55917
|
|
|
55881
55918
|
// If it's a valid date, format it using getFormatDate
|
|
@@ -55892,7 +55929,7 @@ const formatDateAxis = (label, getFormatDateFn) => {
|
|
|
55892
55929
|
* Provides state management and formatting functions for time-based charts
|
|
55893
55930
|
*
|
|
55894
55931
|
* @param {Object} options - Configuration options
|
|
55895
|
-
* @param {string} options.defaultFilter - Default time filter ('daily', 'weekly', 'monthly')
|
|
55932
|
+
* @param {string} options.defaultFilter - Default time filter ('daily', 'weekly', 'monthly', 'yearly')
|
|
55896
55933
|
* @returns {Object} Time filter state and utilities
|
|
55897
55934
|
*/
|
|
55898
55935
|
const useTimeFilter = ({
|
|
@@ -55943,6 +55980,9 @@ const selectOptions$2 = [{
|
|
|
55943
55980
|
}, {
|
|
55944
55981
|
label: "Monthly",
|
|
55945
55982
|
value: "monthly"
|
|
55983
|
+
}, {
|
|
55984
|
+
label: "Yearly",
|
|
55985
|
+
value: "yearly"
|
|
55946
55986
|
}];
|
|
55947
55987
|
const RestoredArea = ({
|
|
55948
55988
|
restoredAreaChart,
|
|
@@ -56086,6 +56126,9 @@ const selectOptions$1 = [{
|
|
|
56086
56126
|
}, {
|
|
56087
56127
|
label: "Monthly",
|
|
56088
56128
|
value: "monthly"
|
|
56129
|
+
}, {
|
|
56130
|
+
label: "Yearly",
|
|
56131
|
+
value: "yearly"
|
|
56089
56132
|
}];
|
|
56090
56133
|
const PlantingActivitiesTimeline = ({
|
|
56091
56134
|
activitiesTimelineChart,
|
|
@@ -56114,6 +56157,11 @@ const PlantingActivitiesTimeline = ({
|
|
|
56114
56157
|
while (lastNonZeroIndex >= 0 && (processedData[lastNonZeroIndex].jobs || 0) === 0) {
|
|
56115
56158
|
lastNonZeroIndex--;
|
|
56116
56159
|
}
|
|
56160
|
+
|
|
56161
|
+
// If all values are 0, return full processed data to show x-axis with default date range
|
|
56162
|
+
if (lastNonZeroIndex < 0) {
|
|
56163
|
+
return processedData;
|
|
56164
|
+
}
|
|
56117
56165
|
return processedData.slice(0, lastNonZeroIndex + 1);
|
|
56118
56166
|
}, [activitiesTimelineChart, processChartDateData]);
|
|
56119
56167
|
const maxActivitiesYValue = React.useMemo(() => {
|
|
@@ -57008,6 +57056,9 @@ const selectOptions = [{
|
|
|
57008
57056
|
}, {
|
|
57009
57057
|
label: "Monthly",
|
|
57010
57058
|
value: "monthly"
|
|
57059
|
+
}, {
|
|
57060
|
+
label: "Yearly",
|
|
57061
|
+
value: "yearly"
|
|
57011
57062
|
}];
|
|
57012
57063
|
const JobsTimeline = ({
|
|
57013
57064
|
dayJobsTimeline,
|
|
@@ -57023,22 +57074,6 @@ const JobsTimeline = ({
|
|
|
57023
57074
|
defaultFilter: 'monthly'
|
|
57024
57075
|
});
|
|
57025
57076
|
const jobsData = Array.isArray(dayJobsTimeline) ? dayJobsTimeline : dayJobsTimeline?.jobsTimeline || dayJobsTimeline?.jobs || dayJobsTimeline?.timeline || [];
|
|
57026
|
-
|
|
57027
|
-
// const jobsTimelineData = useMemo(() => {
|
|
57028
|
-
// // Always process data, even if empty, to generate default date range for x-axis
|
|
57029
|
-
// const dataToProcess = (!jobsData || !Array.isArray(jobsData) || jobsData.length === 0)
|
|
57030
|
-
// ? []
|
|
57031
|
-
// : jobsData;
|
|
57032
|
-
|
|
57033
|
-
// // Process data without cumulative calculation (for jobs timeline)
|
|
57034
|
-
// // Try to find value in total, count, jobs, or value fields
|
|
57035
|
-
// return processChartDateData({
|
|
57036
|
-
// mainData: dataToProcess,
|
|
57037
|
-
// isCumulative: false,
|
|
57038
|
-
// valueField: 'total', // Will fallback to count/jobs/value if total doesn't exist
|
|
57039
|
-
// });
|
|
57040
|
-
// }, [jobsData, processChartDateData]);
|
|
57041
|
-
|
|
57042
57077
|
const jobsTimelineData = React.useMemo(() => {
|
|
57043
57078
|
// Prepare data first
|
|
57044
57079
|
const dataToProcess = !jobsData || !Array.isArray(jobsData) || jobsData.length === 0 ? [] : jobsData;
|
|
@@ -57056,7 +57091,12 @@ const JobsTimeline = ({
|
|
|
57056
57091
|
lastNonZeroIndex--;
|
|
57057
57092
|
}
|
|
57058
57093
|
|
|
57059
|
-
//
|
|
57094
|
+
// If all values are 0, return full processed data to show x-axis with default date range
|
|
57095
|
+
if (lastNonZeroIndex < 0) {
|
|
57096
|
+
return processedData;
|
|
57097
|
+
}
|
|
57098
|
+
|
|
57099
|
+
// Otherwise, slice up to last period with data
|
|
57060
57100
|
return processedData.slice(0, lastNonZeroIndex + 1);
|
|
57061
57101
|
}, [jobsData, processChartDateData]);
|
|
57062
57102
|
const maxYValue = React.useMemo(() => {
|
package/package.json
CHANGED
|
@@ -6,7 +6,7 @@ import { getFormatDate, getTimeQuantity, processChartDateData, formatDateAxis }
|
|
|
6
6
|
* Provides state management and formatting functions for time-based charts
|
|
7
7
|
*
|
|
8
8
|
* @param {Object} options - Configuration options
|
|
9
|
-
* @param {string} options.defaultFilter - Default time filter ('daily', 'weekly', 'monthly')
|
|
9
|
+
* @param {string} options.defaultFilter - Default time filter ('daily', 'weekly', 'monthly', 'yearly')
|
|
10
10
|
* @returns {Object} Time filter state and utilities
|
|
11
11
|
*/
|
|
12
12
|
export const useTimeFilter = ({ defaultFilter = 'monthly' } = {}) => {
|
|
@@ -7,6 +7,7 @@ const selectOptions = [
|
|
|
7
7
|
{ label: "Daily", value: "daily" },
|
|
8
8
|
{ label: "Weekly", value: "weekly" },
|
|
9
9
|
{ label: "Monthly", value: "monthly" },
|
|
10
|
+
{ label: "Yearly", value: "yearly" },
|
|
10
11
|
];
|
|
11
12
|
|
|
12
13
|
const JobsTimeline = ({
|
|
@@ -20,20 +21,6 @@ const JobsTimeline = ({
|
|
|
20
21
|
? dayJobsTimeline
|
|
21
22
|
: (dayJobsTimeline?.jobsTimeline || dayJobsTimeline?.jobs || dayJobsTimeline?.timeline || []);
|
|
22
23
|
|
|
23
|
-
// const jobsTimelineData = useMemo(() => {
|
|
24
|
-
// // Always process data, even if empty, to generate default date range for x-axis
|
|
25
|
-
// const dataToProcess = (!jobsData || !Array.isArray(jobsData) || jobsData.length === 0)
|
|
26
|
-
// ? []
|
|
27
|
-
// : jobsData;
|
|
28
|
-
|
|
29
|
-
// // Process data without cumulative calculation (for jobs timeline)
|
|
30
|
-
// // Try to find value in total, count, jobs, or value fields
|
|
31
|
-
// return processChartDateData({
|
|
32
|
-
// mainData: dataToProcess,
|
|
33
|
-
// isCumulative: false,
|
|
34
|
-
// valueField: 'total', // Will fallback to count/jobs/value if total doesn't exist
|
|
35
|
-
// });
|
|
36
|
-
// }, [jobsData, processChartDateData]);
|
|
37
24
|
|
|
38
25
|
const jobsTimelineData = useMemo(() => {
|
|
39
26
|
// Prepare data first
|
|
@@ -54,7 +41,12 @@ const JobsTimeline = ({
|
|
|
54
41
|
lastNonZeroIndex--;
|
|
55
42
|
}
|
|
56
43
|
|
|
57
|
-
//
|
|
44
|
+
// If all values are 0, return full processed data to show x-axis with default date range
|
|
45
|
+
if (lastNonZeroIndex < 0) {
|
|
46
|
+
return processedData;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
// Otherwise, slice up to last period with data
|
|
58
50
|
return processedData.slice(0, lastNonZeroIndex + 1);
|
|
59
51
|
}, [jobsData, processChartDateData]);
|
|
60
52
|
|
|
@@ -7,6 +7,7 @@ const selectOptions = [
|
|
|
7
7
|
{ label: "Daily", value: "daily" },
|
|
8
8
|
{ label: "Weekly", value: "weekly" },
|
|
9
9
|
{ label: "Monthly", value: "monthly" },
|
|
10
|
+
{ label: "Yearly", value: "yearly" },
|
|
10
11
|
];
|
|
11
12
|
|
|
12
13
|
const PlantingActivitiesTimeline = ({
|
|
@@ -34,6 +35,11 @@ const PlantingActivitiesTimeline = ({
|
|
|
34
35
|
lastNonZeroIndex--;
|
|
35
36
|
}
|
|
36
37
|
|
|
38
|
+
// If all values are 0, return full processed data to show x-axis with default date range
|
|
39
|
+
if (lastNonZeroIndex < 0) {
|
|
40
|
+
return processedData;
|
|
41
|
+
}
|
|
42
|
+
|
|
37
43
|
return processedData.slice(0, lastNonZeroIndex + 1);
|
|
38
44
|
}, [activitiesTimelineChart, processChartDateData]);
|
|
39
45
|
|
|
@@ -6,18 +6,19 @@ import { renderNumber } from './numbers.js';
|
|
|
6
6
|
* Formats a date based on the time filter
|
|
7
7
|
* @param {dayjs.Dayjs} date - The date to format
|
|
8
8
|
* @param {boolean} breakLine - Whether to add a line break (for tooltips)
|
|
9
|
-
* @param {string} timeFilter - The time filter ('daily', 'weekly', 'monthly')
|
|
9
|
+
* @param {string} timeFilter - The time filter ('daily', 'weekly', 'monthly', 'yearly')
|
|
10
10
|
* @returns {string} Formatted date string
|
|
11
11
|
*/
|
|
12
12
|
export const getFormatDate = (date, breakLine = false, timeFilter = 'monthly') => {
|
|
13
13
|
switch (timeFilter) {
|
|
14
14
|
case "daily":
|
|
15
15
|
return date.format("DD/MM");
|
|
16
|
-
case "weekly"
|
|
16
|
+
case "weekly":
|
|
17
17
|
return `W${renderNumber(date.week())}`;
|
|
18
|
+
case "yearly":
|
|
19
|
+
return date.format("YYYY");
|
|
18
20
|
default:
|
|
19
21
|
// Monthly format: "Dec 24", "Jan 25", etc.
|
|
20
|
-
|
|
21
22
|
return breakLine
|
|
22
23
|
? `${capitalize(date.format("MMM"))}\n${date.format("YY")}`
|
|
23
24
|
: `${capitalize(date.format("MMM"))} ${date.format("YY")}`;
|
|
@@ -26,15 +27,20 @@ export const getFormatDate = (date, breakLine = false, timeFilter = 'monthly') =
|
|
|
26
27
|
|
|
27
28
|
/**
|
|
28
29
|
* Gets the time quantity string for dayjs operations
|
|
29
|
-
* @param {string} timeFilter - The time filter ('daily', 'weekly', 'monthly')
|
|
30
|
-
* @returns {string} Time quantity string ('days', 'weeks', 'months')
|
|
30
|
+
* @param {string} timeFilter - The time filter ('daily', 'weekly', 'monthly', 'yearly')
|
|
31
|
+
* @returns {string} Time quantity string ('days', 'weeks', 'months', 'years')
|
|
31
32
|
*/
|
|
32
33
|
export const getTimeQuantity = (timeFilter = 'monthly') => {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
switch (timeFilter) {
|
|
35
|
+
case "daily":
|
|
36
|
+
return "days";
|
|
37
|
+
case "weekly":
|
|
38
|
+
return "weeks";
|
|
39
|
+
case "yearly":
|
|
40
|
+
return "years";
|
|
41
|
+
default:
|
|
42
|
+
return "months";
|
|
43
|
+
}
|
|
38
44
|
};
|
|
39
45
|
|
|
40
46
|
/**
|
|
@@ -62,6 +68,9 @@ export const getPreviousGraphData = (dates, startDate, timeFilter, valueField =
|
|
|
62
68
|
case "weekly":
|
|
63
69
|
isBeforeStart = date.isBefore(startDate, 'week');
|
|
64
70
|
break;
|
|
71
|
+
case "yearly":
|
|
72
|
+
isBeforeStart = date.isBefore(startDate, 'year');
|
|
73
|
+
break;
|
|
65
74
|
default:
|
|
66
75
|
isBeforeStart = date.isBefore(startDate, 'month');
|
|
67
76
|
break;
|
|
@@ -86,7 +95,7 @@ export const getPreviousGraphData = (dates, startDate, timeFilter, valueField =
|
|
|
86
95
|
* Processes chart data with time filtering support
|
|
87
96
|
* @param {Object} params - Parameters object
|
|
88
97
|
* @param {Array} params.mainData - Array of data objects with date and value fields
|
|
89
|
-
* @param {string} params.timeFilter - Time filter ('daily', 'weekly', 'monthly')
|
|
98
|
+
* @param {string} params.timeFilter - Time filter ('daily', 'weekly', 'monthly', 'yearly')
|
|
90
99
|
* @param {Object} params.filters - Optional filters object with timeframe
|
|
91
100
|
* @param {boolean} params.isCumulative - Whether to calculate cumulative values (default: false)
|
|
92
101
|
* @param {string} params.valueField - Field name to extract value from (default: 'total', also checks 'count', 'jobs', 'value')
|
|
@@ -114,6 +123,9 @@ export const processChartDateData = ({
|
|
|
114
123
|
} else if (filter === "weekly") {
|
|
115
124
|
start = start.startOf('week');
|
|
116
125
|
end = end.startOf('week');
|
|
126
|
+
} else if (filter === "yearly") {
|
|
127
|
+
start = start.startOf('year');
|
|
128
|
+
end = end.startOf('year');
|
|
117
129
|
} else {
|
|
118
130
|
start = start.startOf('month');
|
|
119
131
|
end = end.startOf('month');
|
|
@@ -133,9 +145,20 @@ export const processChartDateData = ({
|
|
|
133
145
|
cumulativeScore = hasPreviousData ? previousCumulativeScore : 0;
|
|
134
146
|
}
|
|
135
147
|
|
|
148
|
+
// Get the period unit for comparison
|
|
149
|
+
const getPeriodUnit = (f) => {
|
|
150
|
+
switch (f) {
|
|
151
|
+
case "daily": return "day";
|
|
152
|
+
case "weekly": return "week";
|
|
153
|
+
case "yearly": return "year";
|
|
154
|
+
default: return "month";
|
|
155
|
+
}
|
|
156
|
+
};
|
|
157
|
+
const periodUnit = getPeriodUnit(filter);
|
|
158
|
+
|
|
136
159
|
// Loop until we reach the end date
|
|
137
160
|
let currentDate = start.clone();
|
|
138
|
-
while (currentDate.isBefore(end) || currentDate.isSame(end,
|
|
161
|
+
while (currentDate.isBefore(end) || currentDate.isSame(end, periodUnit)) {
|
|
139
162
|
// Filter data points that fall within this period
|
|
140
163
|
const score = isEmpty ? 0 : dates
|
|
141
164
|
.filter((d) => {
|
|
@@ -146,6 +169,8 @@ export const processChartDateData = ({
|
|
|
146
169
|
case "weekly":
|
|
147
170
|
return dayjs(d.date, "YYYY-MM-DD").week() === currentDate.week() &&
|
|
148
171
|
dayjs(d.date, "YYYY-MM-DD").year() === currentDate.year();
|
|
172
|
+
case "yearly":
|
|
173
|
+
return dayjs(d.date, "YYYY-MM-DD").year() === currentDate.year();
|
|
149
174
|
default:
|
|
150
175
|
return (
|
|
151
176
|
dayjs(d.date, "YYYY-MM-DD").format("YYYY-MM") ===
|
|
@@ -187,7 +212,7 @@ export const processChartDateData = ({
|
|
|
187
212
|
export const formatDateAxis = (label, getFormatDateFn) => {
|
|
188
213
|
if (!label) return label;
|
|
189
214
|
|
|
190
|
-
// Check if label is already in the correct format (MMM YY, DD/MM, or
|
|
215
|
+
// Check if label is already in the correct format (MMM YY, DD/MM, W#, or YYYY)
|
|
191
216
|
// If it matches our format patterns, return as-is
|
|
192
217
|
if (typeof label === 'string') {
|
|
193
218
|
// Check for MMM YY format (e.g., "Dec 24", "Jan 25")
|
|
@@ -202,6 +227,10 @@ export const formatDateAxis = (label, getFormatDateFn) => {
|
|
|
202
227
|
if (/^W\d+$/.test(label)) {
|
|
203
228
|
return label;
|
|
204
229
|
}
|
|
230
|
+
// Check for YYYY format (e.g., "2024", "2025")
|
|
231
|
+
if (/^\d{4}$/.test(label)) {
|
|
232
|
+
return label;
|
|
233
|
+
}
|
|
205
234
|
}
|
|
206
235
|
|
|
207
236
|
// Otherwise, try to parse and format it
|
|
@@ -209,7 +238,7 @@ export const formatDateAxis = (label, getFormatDateFn) => {
|
|
|
209
238
|
|
|
210
239
|
// If first attempt fails, try parsing as ISO date string
|
|
211
240
|
if (!date.isValid() && typeof label === 'string') {
|
|
212
|
-
date = dayjs(label, ['YYYY-MM-DD', 'YYYY-MM', 'MMM YY', 'MMM YYYY', 'DD/MM'], true);
|
|
241
|
+
date = dayjs(label, ['YYYY-MM-DD', 'YYYY-MM', 'YYYY', 'MMM YY', 'MMM YYYY', 'DD/MM'], true);
|
|
213
242
|
}
|
|
214
243
|
|
|
215
244
|
// If it's a valid date, format it using getFormatDate
|