Статистика
Только чтение. Здесь ничего не отмечают — здесь смотрят, что получилось.

Зачем этот экран
Отметки собираются ради одной минуты — когда на них смотрят целиком. Экран показывает четыре разных среза одних и тех же данных: сколько, куда, когда и в каком состоянии.
Периоды здесь — «7 дней», «30 дней» и «Всё время». «Сегодня» нет: один день — это не статистика, это главный экран.
Что на экране
- Четыре плитки — всего часов, всего блоков, в среднем за день, серия дней подряд без пропусков.
- «Наблюдения» — до трёх наблюдений. Блок пропадает целиком, если модуль выключен или сказать пока нечего.
- «Куда уходит время» — приоритеты по убыванию, с часами и долями. Сюда же попадают удалённые приоритеты с пометкой «архив», если у них есть время в этом периоде.
- «По дням» — столбики.
- «Заряд» — полоса состояний, список уровней, график энергии.
- «Что сажает батарею» — ответы на вопрос «что съело энергию».
Как этим пользоваться
Разобрать конкретный день

Высота столбца — сколько отмечено за день, цвета внутри — из чего сложилось. Нажмите на столбик, чтобы развернуть день по приоритетам.

Цвета внутри столбца идут в порядке вашего списка приоритетов, а не по величине — иначе они прыгали бы от дня ко дню и картинка перестала бы читаться.
Посмотреть, в каком состоянии прошёл период

Полоса — доли состояний за период; список под ней — то же самое числами.
Как менялась энергия

Линия — средний заряд за день: сверху «полный», снизу «на нуле». Пунктир — среднее за весь период. Столбики под линией показывают, из каких состояний сложились сутки. Нажатие на день разбирает его.
Важно: «Заряжаюсь» в эту шкалу не входит. Восстановление — это занятие, а не величина заряда, и день, целиком проведённый в восстановлении, оставляет в графике разрыв, а не точку на нуле. Разрыв честнее ложного нуля.
Что сажает батарею

Тут считаются переходы, а не дни: «3 раза», а не «3 дня». Строка «Не знаю» — полноправный ответ, а не отсутствие ответа.
Ответы своими словами стоят здесь отдельными строками, без цвета: цвет есть у приоритета, а у чужой причины его нет. Одинаковый текст — одна строка со счётчиком.
Сменить масштаб

На «30 днях» столбики уплотняются и подписи дней исчезают: на тридцати колонках они не читаются. «Всё время» растягивает окно от первой записи до сегодня.
Пустое состояние

Плитки остаются (ноль — тоже число), а разделы «Куда уходит время» и «Заряд» заменяются объяснениями.
Пределы и предупреждения
- Серия считается по дням с хотя бы одним блоком. Сегодняшний пустой день серию ещё не рвёт — она обрывается только когда пропущен целый прошедший день.
- Средний за день делится на все дни периода, включая пустые, а не только на дни с отметками.
- Доли и часы пересчитываются при смене цены блока, потому что хранятся клики, а не минуты.
- Глубина хранения — 13 месяцев. «Всё время» дальше не заглядывает, см. «Данные и синхронизация».
- Наблюдения не следуют переключателю периода: у них свои фиксированные окна.
Чего здесь нельзя
- Ничего изменить. Экран только читает; исправление блоков — на главной.
- Выбрать произвольный интервал. Три периода, других нет.
- Выгрузить отчёт. Есть только полная копия данных в JSON.
- Увидеть навыки. У них своя вкладка и свой счёт времени.
Рядом
Наблюдения · Заряд · Данные и синхронизация · Приоритеты
Как это работает внутри
- Экран —
src/screens/StatsScreen.tsx. Вся арифметика вынесена вsrc/domain/stats.tsи покрытаsrc/domain/stats.test.ts. computeStatsвозвращаетshare(доля периода) иfill(доля относительно лидера); лидер считается по активным и архивным сразу.- Серия —
clickStreak: перед подсчётом функция отступает на день назад, поэтому пустое «сегодня» серию не рвёт. Рекордная серия (bestStreak) считается отдельно, чтобы полученное достижение не пропадало вместе с прервавшейся серией. - Средний заряд —
chargeLevel(minutes)с весами{1: 0, 2: 0.5, 3: 1}. Уровень 4 в весах отсутствует; когда усреднять нечего, функция возвращаетnull, иEnergyChartрисует разрыв. - Столбики —
dailyBreakdown: сегменты идут в порядке приоритетов пользователя, а сегмент с неизвестным идентификатором пропускается, а не рисуется без подписи. - Причины разряда —
drainCounts, ключDRAIN_UNKNOWN = '?'остаётся в выдаче. Ключи с префиксом!— ответы своими словами; подпись строки берётся из самого ключа черезdrainTextOf, поэтому группировка «одинаковый текст — одна строка» получается сама, без сверки со списком приоритетов. - Компоненты графиков:
src/components/DayBars.tsxиsrc/components/EnergyChart.tsx— оба на голом SVG, без библиотек.