Skip to content

fix(plot): stop calling plotted points "samples"; correct the listing char count - #121

Merged
cptkoolbeenz merged 3 commits into
mainfrom
fix/plot-sample-count
Aug 14, 2026
Merged

cptkoolbeenz merged 3 commits into
mainfrom
fix/plot-sample-count

Conversation

@cptkoolbeenz

Copy link
Copy Markdown
Member

Two display-accuracy corrections. No behaviour change to the data path.

The live plot called plotted points "samples"

Refs #120.

The readout said "5,296 samples" on a data-acquisition app, which reads as an acquisition total. It is not one. MobileShellViewModel.PollActiveSamples appends at most one point per channel per render tick (20 Hz), so at 16 channels / 100 Hz the device delivers ~1,600 samples/s while this counter sees ~320 — about a fifth.

This also explains a number that ran through the whole release effort: every "samples/s" figure measured while validating the foreground service (~333–347/s) was really this poll rate, not the acquisition rate. Those measurements remain valid as a comparison — the same metric on both sides of the background test — but they were never the device's sample rate.

Now reads "N points plotted", and the property carries the arithmetic so the next reader does not have to re-derive it.

Deliberately not fixing the decimation here. Counting the true total means incrementing in the shared streaming hot path (AbstractStreamingDevice, ~1,600/s, on Core's transport thread), and min/max decimation so short transients survive is a larger plot change. Neither is a sensible risk days before a production flip. Both stay scoped in #120.

Recorded data was never affected. Logging runs off the per-frame device message (DispatchDeviceMessage → LoggingManager), not off this poll, so a CSV export has always contained every sample. Only the live view is decimated.

The listing copy's character count was stale

Removing the false "works with more than one device at a time" bullet (that claim is untrue — MobileShellViewModel holds a single _connected device) shortened the text, but the stated count stayed at the pre-removal 1616. Verified programmatically against the actual block: 1572. The number is the only signal that the copy still fits Play's 4000-character limit without pasting it in to find out.

Follow-up, not in this PR

The four committed store screenshots still show the old "samples" wording. They need regenerating so the listing matches the app — the bench device is mid-soak for #116 right now, so that lands separately.

Refs #120.

The live readout said "5,296 samples" on a data-acquisition app, which
reads as an acquisition total. It is not. The view-model appends at most
one point per channel per render tick (20 Hz), so at 16 channels / 100 Hz
the device delivers ~1,600 samples/s while this counted ~320 — about a
fifth. Every "samples/s" figure measured during this release work was
really this poll rate, which is why they all landed near 340 rather than
1,600.

Now reads "N points plotted", and the property carries the arithmetic so
the next reader does not have to rediscover it.

Deliberately NOT fixing the underlying decimation in this commit. Counting
the true total means incrementing in the shared streaming hot path
(AbstractStreamingDevice, ~1,600/s, off the transport thread), and min/max
decimation so transients survive is a larger plot change. Neither is a
sensible risk days before a production flip, and both are already scoped
in #120. This removes the false claim at zero risk to the data path.

Recorded data was never affected: logging runs off the per-frame device
message, not this poll, so a CSV export has always held every sample.
Removing the false "works with more than one device" bullet shortened the
text, but the stated count was left at the pre-removal 1616. Verified
against the actual block: 1572.

The number matters because it is the only signal that the copy still fits
Play's 4000-character limit without pasting it in to find out.
@qodo-code-review

Copy link
Copy Markdown

PR Summary by Qodo

Fix live plot counter wording and update store listing character count

🐞 Bug fix 📝 Documentation 🕐 10-20 Minutes

Grey Divider

AI Description

• Rename live plot readout from "samples" to "points plotted" to avoid acquisition-rate confusion.
• Document why the plotted-point counter is decimated and not the true sample total.
• Correct the Play Store full-description character count to match current copy.
Diagram

graph TD
  A["LivePlot.cs"] --> B["SampleCount remarks"] --> C["Header text"] --> D["Live plot UI"]
  E["store/listing-copy.md"] --> F["Play Store listing"]
Loading
High-Level Assessment

The following are alternative approaches to this PR:

1. Rename SampleCount to PointCount (and keep UI wording)
  • ➕ Aligns property name with meaning; reduces future confusion in code usage
  • ➖ Potentially wider refactor ripple if referenced broadly; higher risk close to release
2. Track true acquired sample count in streaming hot path
  • ➕ Would provide an accurate acquisition total/rate
  • ➕ Enables correct analytics/telemetry based on real samples
  • ➖ Touches shared high-frequency streaming/transport code path; higher regression risk
  • ➖ Still doesn’t solve decimation/visual-transient fidelity without additional work
3. Expose both metrics: acquired samples and plotted points
  • ➕ Eliminates ambiguity; supports both data-integrity and UI-throughput diagnostics
  • ➖ More UI surface area and copy decisions; additional plumbing required

Recommendation: Keep the PR’s current low-risk approach: relabel the UI to "points plotted" and encode the decimation explanation in code comments. Defer any true-sample counting and decimation strategy changes to the scoped follow-up (#120), where the higher-risk streaming-path modifications and plot fidelity changes can be reviewed together.

Files changed (2) +20 / -4

Bug fix (1) +19 / -3
LivePlot.csRelabel plotted-point counter and document decimation semantics +19/-3

Relabel plotted-point counter and document decimation semantics

• Rewords the live plot header from "N samples" to "N points plotted". Expands the SampleCount documentation to clarify it represents decimated plotted points (render-tick append), not total acquired samples, and notes why true counting is deferred.

Daqifi.Avalonia/Views/LivePlot.cs

Documentation (1) +1 / -1
listing-copy.mdFix Play Store description character-count indicator +1/-1

Fix Play Store description character-count indicator

• Updates the tracked character count for the full description block from 1616 to 1572 to reflect current listing copy length.

store/listing-copy.md

@qodo-code-review

qodo-code-review Bot commented Aug 14, 2026 •

Copy link
Copy Markdown

Code Review by Qodo

🐞 Bugs (0) 📘 Rule violations (0) 📎 Requirement gaps (0) 🎨 UX issues (0) 🔗 Cross-repo conflicts (0) 📜 Skill insights (0)

Grey Divider


Remediation recommended

1. Unclamped header plate width ✓ Resolved 🐞 Bug ⚙ Maintainability
Description
LivePlot.Render sizes the header background plate directly from the formatted header text width,
without clamping to the control bounds; with the longer "points plotted" label, the plate can extend
beyond the control when the text doesn’t fit. This can cause drawing outside the plot region unless
clipping is enabled by the host/control.
Code

Daqifi.Avalonia/Views/LivePlot.cs[R130-133]

+        // Header: points plotted — the definitive "is data flowing?" readout. Deliberately not
+        // "samples": see the SampleCount remarks. The plot shows a 20 Hz decimation of the stream.
        var header = new FormattedText(
-            $"{SampleCount:N0} samples", CultureInfo.CurrentCulture,
+            $"{SampleCount:N0} points plotted", CultureInfo.CurrentCulture,
Relevance

●●● Strong

Small, directly-related render robustness tweak; similar LivePlot.Render quality fixes were accepted
recently.

PR-#112

ⓘ Recommendations generated based on similar findings in past PRs

Evidence
The PR increases the header text length, while the plate width is derived from measured text width
and is not bounded by the control width. The LivePlot is hosted in MobileShellView without
ClipToBounds being set on the container/control, so any oversize header is not obviously prevented
from painting outside the plot region by local code.

Daqifi.Avalonia/Views/LivePlot.cs[125-138]
Daqifi.Avalonia/Views/MobileShellView.axaml[109-112]

Agent prompt
The issue below was found during a code review. Follow the provided context and guidance below and implement a solution

## Issue description
`LivePlot.Render` computes the header plate width from `header.Width + padding` and does not constrain it to the control’s available width. The PR changes the header label to a longer string, increasing the likelihood that the plate (and/or text) won’t fit and will draw past the control’s right edge.

## Issue Context
This is driven on a render timer and used in `MobileShellView` inside a `Panel`. The safest fix is to either (a) clamp the plate width to `Bounds.Width` and clip the header draw region, or (b) enable `ClipToBounds` for `LivePlot` in the hosting XAML.

## Fix Focus Areas
- Daqifi.Avalonia/Views/LivePlot.cs[130-138]
- Daqifi.Avalonia/Views/MobileShellView.axaml[109-112]

ⓘ Copy this prompt and use it to remediate the issue with your preferred AI generation tools


Grey Divider

Tip of the day
💡 Did you know, you can describe a rule in plain language on the Rules page and Qodo drafts it for you

More tips ↗ | Customize Qodo ↗ | Qodo docs ↗

Grey Divider

Qodo Logo

Comment thread Daqifi.Avalonia/Views/LivePlot.cs Resolved
Both plates are sized from measured text, with no bound. Making the
header label longer ("N points plotted" replacing "N samples") is what
surfaced it, but the legend plate has the same shape and the same risk —
its width comes from the widest channel label.

Nothing local sets ClipToBounds, so an oversize plate paints outside the
plot region rather than being cut off. Clamped both to the control width.

Realistically the header needs a very large count or a narrow layout to
overflow, which is why it had not been seen. That is an argument for
fixing it now rather than treating it as theoretical: the failure only
appears at the sample counts a long acquisition produces, which is the
case least likely to be caught by hand and most likely to be a user's
real session.
@cptkoolbeenz

Copy link
Copy Markdown
Member Author

/agentic_review

@qodo-code-review

Copy link
Copy Markdown

Code review by qodo was updated up to the latest commit 3e3418d

@cptkoolbeenz
cptkoolbeenz merged commit e84df14 into main Aug 14, 2026
3 checks passed
@cptkoolbeenz
cptkoolbeenz deleted the fix/plot-sample-count branch August 14, 2026 23:56
cptkoolbeenz added a commit that referenced this pull request Aug 15, 2026
…label (#123)

The committed set showed "N samples", which the app no longer says (#120,
merged in e84df14). A store listing whose screenshots disagree with the
running app is the kind of small wrongness a reviewer notices and a user
trusts less.

The hero shot is also simply better than what it replaces: three
phase-staggered sines at a low enough sample depth to show three clean
cycles, rather than the ten crammed ones the earlier capture had. It also
exercises the plate-width clamp from #121 — the plate now hugs "201
points plotted" instead of running to a guessed width.

Screens 03 and 04 are byte-identical to the previous set. That is
expected, not a failed capture: the 90px crop removes the status bar with
its clock, and neither the channel picker nor the scan result has other
time-varying content.

All four remain 1080x2160 — Play's 2:1 cap, and 1080 on the short side
for promotion eligibility.
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.

1 participant