Analysis: read a rarely-read meter as coarse, not absent; newest rows first
ci / build-test (push) Successful in 2m41s

Three things a reported Heizoel page got wrong at once. Its tank is dipped
a few times a year and its burner read every few months, which is exactly
the shape the coverage rules had not been walked through.

"No data" for data that exists. A tank books nothing until the next
dipstick closes the interval, so the stretch after the last dipstick is
covered by no run at all, and a bucket no run covers was reported missing.
The burner, whose run reaches into the window, said "only coarser data" --
the honest answer -- so one card claimed there was nothing while the
coverage panel beside it listed years of data. A bucket that no run covers,
no gap overlaps and no opening balance explains now reports the meter's
resolution when its preceding coverage is within one interval of its own
class: it is not silent, it is read rarely. A meter that does book its own
buckets and stops -- a dead hourly source, a sheet asked about a later
month -- still reads missing.

Auto answering twelve months with one bar. Coarse only means "longer than
a month", so a dipstick taken each autumn straddles a New Year as surely
as a month start: coarsening the chart to years bought nothing and cost
every point. The planning resolution now caps coarse at month when a run
crosses a local year edge, and a series that cannot resolve the natural
size no longer coarsens the whole chart -- it is drawn at that size with
its buckets marked, which the chart and table already explain.

A page contradicting itself. The comparison line above the ranking was fed
the leading measure's matched coverage but worded as if it spoke for the
page, directly above a burner row that did compare. It now names the figure
it is about.

Alongside: the "largest changes" ranking no longer drops a meter whose
change is not comparable. It ranks what can be ranked, then lists the rest
with their values and the reason -- the tank had been vanishing from its
own energy type. And every dated table now reads newest first, as lists
are read; charts stay chronological left to right, and the CSV export
stays ascending for spreadsheets.

A-41 to A-43 in the note record the three rules.
This commit is contained in:
Florian Schmidt
2026-09-20 12:44:32 +02:00
parent 5a6f34a467
commit a08e9f781f
38 changed files with 1301 additions and 184 deletions
@@ -1,7 +1,8 @@
@* The accessible alternative to the chart (brief §7.2): one row per bucket with the period label, each series' value
with its unit, the status in words (availability, reason, provenance), the optional cost and price coverage, the
optional comparison (with the bucket it is compared with) and the change, a total row, and a drill-down per row.
A wide table scrolls inside its own container, never the page. *@
A wide table scrolls inside its own container, never the page.
The rows read newest first with the total above them (A-42); the chart beside it stays chronological. *@
@if (_model is not null && _model.Rows.Count > 0)
{
@@ -79,7 +80,7 @@
}
@code {
/// <summary>The buckets of the plan, oldest first.</summary>
/// <summary>The buckets of the plan, oldest first; the table turns them round itself (A-42).</summary>
[Parameter, EditorRequired]
public IReadOnlyList<AnalysisBucket> Buckets { get; set; } = [];