comparison
This commit is contained in:
@@ -32,6 +32,9 @@ const getStartOfWeek = (d: Date) => {
|
||||
return startOfDay(date);
|
||||
};
|
||||
|
||||
const shiftDate = (d: Date, days: number) =>
|
||||
new Date(d.getTime() + days * 86400000);
|
||||
|
||||
// ---------------- LATEST ----------------
|
||||
export async function fetchLatestTransactions(
|
||||
type: "expense" | "income"
|
||||
@@ -106,13 +109,20 @@ export async function fetchAggregatedData(
|
||||
const normalize = (amt: number) => Math.abs(amt);
|
||||
|
||||
// ---------------- DAILY ----------------
|
||||
const dailyBuckets: Record<string, number> = {
|
||||
Mon: 0, Tue: 0, Wed: 0, Thu: 0,
|
||||
Fri: 0, Sat: 0, Sun: 0
|
||||
const dailyBuckets: Record<string, any> = {
|
||||
Mon: { amount: 0, compare: 0 },
|
||||
Tue: { amount: 0, compare: 0 },
|
||||
Wed: { amount: 0, compare: 0 },
|
||||
Thu: { amount: 0, compare: 0 },
|
||||
Fri: { amount: 0, compare: 0 },
|
||||
Sat: { amount: 0, compare: 0 },
|
||||
Sun: { amount: 0, compare: 0 }
|
||||
};
|
||||
|
||||
const weekStart = getStartOfWeek(now);
|
||||
const weekEnd = endOfDay(new Date(weekStart.getTime() + 6 * 86400000));
|
||||
const prevWeekStart = shiftDate(weekStart, -7);
|
||||
const prevWeekEnd = shiftDate(weekEnd, -7);
|
||||
|
||||
// ---------------- WEEKLY ----------------
|
||||
const weeklyRolling: any[] = [];
|
||||
@@ -120,7 +130,7 @@ export async function fetchAggregatedData(
|
||||
|
||||
const currentWeekStart = getStartOfWeek(now);
|
||||
|
||||
// rolling (last 5 weeks, oldest → newest)
|
||||
// rolling (last 5 weeks)
|
||||
for (let i = 4; i >= 0; i--) {
|
||||
const start = new Date(currentWeekStart.getTime() - i * 7 * 86400000);
|
||||
const end = endOfDay(new Date(start.getTime() + 6 * 86400000));
|
||||
@@ -129,11 +139,14 @@ export async function fetchAggregatedData(
|
||||
label: `${format(start)} - ${format(end)}`,
|
||||
start,
|
||||
end,
|
||||
amount: 0
|
||||
amount: 0,
|
||||
compare: 0,
|
||||
prevStart: shiftDate(start, -7),
|
||||
prevEnd: shiftDate(end, -7)
|
||||
});
|
||||
}
|
||||
|
||||
// calendar (full weeks covering current month)
|
||||
// calendar weeks
|
||||
const startOfMonth = new Date(now.getFullYear(), now.getMonth(), 1);
|
||||
const endOfMonth = new Date(now.getFullYear(), now.getMonth() + 1, 0);
|
||||
|
||||
@@ -151,7 +164,10 @@ export async function fetchAggregatedData(
|
||||
label: `${format(start)} - ${format(end)}`,
|
||||
start,
|
||||
end,
|
||||
amount: 0
|
||||
amount: 0,
|
||||
compare: 0,
|
||||
prevStart: shiftDate(start, -7),
|
||||
prevEnd: shiftDate(end, -7)
|
||||
});
|
||||
}
|
||||
|
||||
@@ -159,7 +175,7 @@ export async function fetchAggregatedData(
|
||||
const monthlyRolling: any[] = [];
|
||||
const monthlyCalendar: any[] = [];
|
||||
|
||||
// rolling (last 12 months, oldest → newest)
|
||||
// rolling (last 12 months)
|
||||
for (let i = 11; i >= 0; i--) {
|
||||
const d = new Date(now);
|
||||
d.setMonth(d.getMonth() - i);
|
||||
@@ -170,24 +186,44 @@ export async function fetchAggregatedData(
|
||||
? endOfDay(now)
|
||||
: endOfDay(new Date(d.getFullYear(), d.getMonth() + 1, 0));
|
||||
|
||||
const prevStart = new Date(start);
|
||||
prevStart.setMonth(prevStart.getMonth() - 1);
|
||||
const prevEnd = new Date(end);
|
||||
prevEnd.setMonth(prevEnd.getMonth() - 1);
|
||||
|
||||
monthlyRolling.push({
|
||||
label: `${d.toLocaleString("default", { month: "short" })}-${String(d.getFullYear()).slice(2)}`,
|
||||
label: `${d.toLocaleString("default", { month: "short" })}-${String(
|
||||
d.getFullYear()
|
||||
).slice(2)}`,
|
||||
start,
|
||||
end,
|
||||
amount: 0
|
||||
amount: 0,
|
||||
compare: 0,
|
||||
prevStart,
|
||||
prevEnd
|
||||
});
|
||||
}
|
||||
|
||||
// calendar (full year Jan → Dec)
|
||||
// calendar (Jan–Dec)
|
||||
for (let i = 0; i < 12; i++) {
|
||||
const start = new Date(now.getFullYear(), i, 1);
|
||||
const end = endOfDay(new Date(now.getFullYear(), i + 1, 0));
|
||||
|
||||
const prevStart = new Date(start);
|
||||
prevStart.setFullYear(prevStart.getFullYear() - 1);
|
||||
const prevEnd = new Date(end);
|
||||
prevEnd.setFullYear(prevEnd.getFullYear() - 1);
|
||||
|
||||
monthlyCalendar.push({
|
||||
label: `${start.toLocaleString("default", { month: "short" })}-${String(start.getFullYear()).slice(2)}`,
|
||||
label: `${start.toLocaleString("default", { month: "short" })}-${String(
|
||||
start.getFullYear()
|
||||
).slice(2)}`,
|
||||
start,
|
||||
end,
|
||||
amount: 0
|
||||
amount: 0,
|
||||
compare: 0,
|
||||
prevStart,
|
||||
prevEnd
|
||||
});
|
||||
}
|
||||
|
||||
@@ -210,38 +246,51 @@ export async function fetchAggregatedData(
|
||||
// DAILY
|
||||
if (d >= weekStart && d <= weekEnd) {
|
||||
const day = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][d.getDay()];
|
||||
if (dailyBuckets[day] !== undefined) {
|
||||
dailyBuckets[day] += amt;
|
||||
if (dailyBuckets[day]) {
|
||||
dailyBuckets[day].amount += amt;
|
||||
}
|
||||
}
|
||||
|
||||
if (d >= prevWeekStart && d <= prevWeekEnd) {
|
||||
const day = ["Sun","Mon","Tue","Wed","Thu","Fri","Sat"][d.getDay()];
|
||||
if (dailyBuckets[day]) {
|
||||
dailyBuckets[day].compare += amt;
|
||||
}
|
||||
}
|
||||
|
||||
// WEEKLY
|
||||
for (const b of weeklyRolling) {
|
||||
if (d >= b.start && d <= b.end) b.amount += amt;
|
||||
if (d >= b.prevStart && d <= b.prevEnd) b.compare += amt;
|
||||
}
|
||||
for (const b of weeklyCalendar) {
|
||||
if (d >= b.start && d <= b.end) b.amount += amt;
|
||||
if (d >= b.prevStart && d <= b.prevEnd) b.compare += amt;
|
||||
}
|
||||
|
||||
// MONTHLY
|
||||
for (const b of monthlyRolling) {
|
||||
if (d >= b.start && d <= b.end) b.amount += amt;
|
||||
if (d >= b.prevStart && d <= b.prevEnd) b.compare += amt;
|
||||
}
|
||||
for (const b of monthlyCalendar) {
|
||||
if (d >= b.start && d <= b.end) b.amount += amt;
|
||||
if (d >= b.prevStart && d <= b.prevEnd) b.compare += amt;
|
||||
}
|
||||
}
|
||||
|
||||
const toPoints = (arr: any[]): ChartDataPoint[] =>
|
||||
arr.map((x) => ({
|
||||
id: x.label,
|
||||
amount: x.amount
|
||||
amount: x.amount,
|
||||
compareAmount: x.compare
|
||||
}));
|
||||
|
||||
const chartData: ChartData = {
|
||||
daily: Object.entries(dailyBuckets).map(([k, v]) => ({
|
||||
daily: Object.entries(dailyBuckets).map(([k, v]: any) => ({
|
||||
id: k,
|
||||
amount: v
|
||||
amount: v.amount,
|
||||
compareAmount: v.compare
|
||||
})),
|
||||
weekly: {
|
||||
rolling: toPoints(weeklyRolling),
|
||||
@@ -253,7 +302,7 @@ export async function fetchAggregatedData(
|
||||
}
|
||||
};
|
||||
|
||||
// highlight max (per visible set default to rolling)
|
||||
// highlight max (current only)
|
||||
Object.values(chartData).forEach((group: any) => {
|
||||
const arr = Array.isArray(group) ? group : group.rolling;
|
||||
if (!arr?.length) return;
|
||||
|
||||
Reference in New Issue
Block a user