Skip to content

feat: category chart as a share of the month, with names and a back button - #19

Merged
santidev21 merged 2 commits into
mainfrom
feat/category-chart-share-and-breakdown-back
Sep 30, 2026
Merged

santidev21 merged 2 commits into
mainfrom
feat/category-chart-share-and-breakdown-back

Conversation

@santidev21

Copy link
Copy Markdown
Owner

What

  • 📊 Categorías chart: each bar is now the category's share of the month's total (100 % fills the row), instead of a fraction of the largest category. The row carries the category name at the left and $gasto (share %) at the right, with the bar underneath; all rows share one scale, so two bars are directly comparable. The budget detail ($gastado de $presupuesto (uso %)) stays in the numbered legend in the caption.
  • Bitmap font: BitmapFont gained A-Z, a-z and the punctuation a name needs, folds accents before drawing (á → a, because a 5x7 glyph cannot hold a diacritic) and adds Truncate, which cuts a name that does not fit and marks the cut with ... The p, q, g and y glyphs were reseated on the x-height band — queso used to read as 9ueso. Icons and other scripts still leave a blank, which is why the exact name keeps its place in the caption.
  • Breakdown back button: "📂 ¿Qué categoría quieres revisar?" ends in an ↩️ Volver row that hands off to the summary (catdetail:summary), so the screen has an exit besides the persistent menu — also when the month has no movements.

Why

Two issues reported against the summary/statistics flows:

  1. The category chooser had no way back.
  2. The chart's percentage did not match the bar's length: the bar was scaled against the longest category while the label showed the budget usage percentage, so a "3 %" category could be drawn almost halfway across the image. The category name was also missing from the image.

No message keys were added: the back row reuses Buttons.Back.

How to test

dotnet build MyBudget.sln                 # zero warnings
dotnet test MyBudget.sln                  # 835 green, +7 new
dotnet format MyBudget.sln --verify-no-changes

Manual, over Telegram:

  1. 📊 Resumen → 📂 Por categoría → a category → the movements screen → ↩️ Volver returns to the chooser, and the chooser's ↩️ Volver returns to the summary.
  2. 📈 Estadísticas → 📊 Categorías: the percentage on each row matches the bar's length against the full row width, the category name is drawn above each bar, and the budget stays in the numbered legend below the image.

Checklist

  • CI is green (build, tests, formatting, security scans).
  • New/changed behavior is covered by tests (bar share over the total, bar ratio, name above the bar, letters/accents/unknown glyphs, Truncate, chooser back row and its handoff).
  • Money stays exact (long) and dates are calendar dates where relevant.
  • No secrets, credentials or .env values are committed.
  • Docs (AGENTS.md, docs/) updated if behavior or conventions changed.
  • Changes are focused and reasonably small.

…own back button

The horizontal bars were measured against the largest category while the row
labelled the budget usage percentage, so a "3 %" category could be drawn almost
halfway across the image. Bars are now a share of the total they are given
(HorizontalBars(entries, total)), every row shares one scale, and the label
carries the amount with that same share. The budget detail stays in the
numbered legend under the chart.

Drawing the category name needed letters: BitmapFont gained A-Z, a-z and the
punctuation a name needs, folds accents (a 5x7 glyph cannot hold a diacritic)
and truncates what does not fit with "..". The p, q, g and y glyphs were also
reseated on the x-height band, where "queso" used to read as "9ueso". Icons and
other scripts still leave a blank, which is why the exact name keeps its place
in the caption.

The breakdown chooser ends in a back row that hands off to the summary, so the
screen has an exit besides the persistent menu, even when the month has no
movements.
Comment on lines +97 to +103
foreach (var character in decomposed)
{
if (CharUnicodeInfo.GetUnicodeCategory(character) != UnicodeCategory.NonSpacingMark)
{
builder.Append(character);
}
}
/// <param name="total">
/// What the bars are a share of: 100 % fills a row, so a 3 % category is 3 % of the row.
/// </param>
public static byte[] HorizontalBars(IReadOnlyList<ChartEntry> entries, long total) =>
@santidev21
santidev21 merged commit 7ad3a61 into main Sep 30, 2026
11 of 14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants