Add percentage of total to top expense categories on dashboard

Show what percentage of total expenses each category represents in the top categories table. This helps quickly identify which categories consume the largest portion of spending.

Changes:
- Add PercentageOfTotal property to TopCategoryRow
- Calculate percentage based on total expenses in the period
- Display percentage as a badge in the table (e.g., "23.5%")
- Add new "% of Total" column header
- Format to 1 decimal place for clarity

Example: If "Groceries" is $500 and total expenses are $2000, it shows 25.0%

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
AJ
2025-10-12 02:13:57 -04:00
parent 52615eeb75
commit ecb7851a62
2 changed files with 19 additions and 4 deletions

View File

@@ -71,6 +71,7 @@
<tr> <tr>
<th>Category</th> <th>Category</th>
<th class="text-end">Total Spend</th> <th class="text-end">Total Spend</th>
<th class="text-end">% of Total</th>
<th class="text-end">Txns</th> <th class="text-end">Txns</th>
</tr> </tr>
</thead> </thead>
@@ -84,6 +85,9 @@
</a> </a>
</td> </td>
<td class="text-end">@c.TotalSpend.ToString("C")</td> <td class="text-end">@c.TotalSpend.ToString("C")</td>
<td class="text-end">
<span class="badge bg-secondary">@c.PercentageOfTotal.ToString("F1")%</span>
</td>
<td class="text-end">@c.Count</td> <td class="text-end">@c.Count</td>
</tr> </tr>
} }

View File

@@ -44,6 +44,7 @@ namespace MoneyMap.Pages
public string Category { get; set; } = ""; public string Category { get; set; } = "";
public decimal TotalSpend { get; set; } public decimal TotalSpend { get; set; }
public int Count { get; set; } public int Count { get; set; }
public decimal PercentageOfTotal { get; set; }
} }
public class RecentTxnRow public class RecentTxnRow
@@ -176,20 +177,30 @@ namespace MoneyMap.Pages
{ {
var since = DateTime.UtcNow.Date.AddDays(-lastDays); var since = DateTime.UtcNow.Date.AddDays(-lastDays);
return await _db.Transactions // Get all expense transactions for the period
var expenseTransactions = await _db.Transactions
.Where(t => t.Date >= since && t.Amount < 0) .Where(t => t.Date >= since && t.Amount < 0)
.ExcludeTransfers() // Exclude credit card payments and transfers .ExcludeTransfers() // Exclude credit card payments and transfers
.ToListAsync();
// Calculate total spend
var totalSpend = expenseTransactions.Sum(t => -t.Amount);
// Group by category and calculate percentages
var topCategories = expenseTransactions
.GroupBy(t => t.Category ?? "") .GroupBy(t => t.Category ?? "")
.Select(g => new IndexModel.TopCategoryRow .Select(g => new IndexModel.TopCategoryRow
{ {
Category = g.Key, Category = g.Key,
TotalSpend = g.Sum(x => -x.Amount), TotalSpend = g.Sum(x => -x.Amount),
Count = g.Count() Count = g.Count(),
PercentageOfTotal = totalSpend > 0 ? (g.Sum(x => -x.Amount) / totalSpend) * 100 : 0
}) })
.OrderByDescending(x => x.TotalSpend) .OrderByDescending(x => x.TotalSpend)
.Take(count) .Take(count)
.AsNoTracking() .ToList();
.ToListAsync();
return topCategories;
} }
} }