Skip to content

Stack the slices of a whole, and dash the lines among them - #32

Merged
evandhoffman merged 1 commit into
mainfrom
feat/issue-24-stacked-parts
Aug 19, 2026
Merged

Stack the slices of a whole, and dash the lines among them#32
evandhoffman merged 1 commit into
mainfrom
feat/issue-24-stacked-parts

Conversation

@evandhoffman

Copy link
Copy Markdown
Contributor

Summary

  • Stack the parts of a whole, a second checkbox on the Charts tab. On, Memory draws App/Wired/Compressed/Cached/Free as stacked bands, and CPU draws User/System the same way. Off by default.
  • A metric declares whether it is a slice. MetricDescriptor.composition is .part, .aggregate or nil — same shape as direction, and for the same reason: a fact about the metric, so a source added later gets stacking for free. CPU turned out to be the same shape as Memory, since cpu.total = (user + system) / total exactly.
  • An aggregate must never be a band, which is what the whole feature turns on. Memory Used is app + wired + compressed, so stacking it counts those three twice and puts the top of the card at nearly twice the machine's RAM. It keeps a line and lands exactly on the bands it sums. Swap keeps a line too — it is on disk, not in RAM.
  • Lines among bands are dashed, with a hollow legend swatch instead of a filled one. A solid stroke among slices invites reading a sum as one more slice.
  • The y-axis is bounded by the summed height, not the tallest band. Memory already had a nominalMaximum of physical RAM; a stacked group without one would have overflowed the card.
  • Stacked and mirrored are exclusive — by declaration, by a registry test, and again in ChartCard, because a band below a baseline is nonsense however it got there.

Closes #24

Test plan

  • swift build && swift test — 175 tests in 20 suites
  • swift build -c release
  • swiftformat Sources Tests --lint --cache ignore — clean
  • The issue's open question ("do the memory metrics sum to a total without double-counting?") is answered by a test that reads the real machine, not a fixture: the slices account for 85–102% of physical RAM, so they cannot overlap, and Used is strictly larger than any one of them. CPU is checked as the exact identity it is.
  • Checked on screen in swift run monitor: Memory and CPU stack; Used and Total land on top of the bands they sum; the dashed lines and hollow swatches read clearly; Disk and Network are untouched by the setting

https://claude.ai/code/session_01UPbN2SqYq8t2vcx2YWQTcs

Memory is not seven independent readings. App, wired, compressed, cached and
free are five slices of one machine's RAM, and five lines climbing from zero
answer "how big is each part" while hiding the question you opened the card for:
how full is the machine. Stacked, the bands answer both.

A metric declares whether it is a slice. MetricDescriptor.composition is .part,
.aggregate or nil -- the same shape as direction, and for the same reason: it is
a fact about the metric, so a source added later gets stacking without anything
else being told. CPU turns out to be the same shape as Memory, since total is
user plus system exactly.

An aggregate must never be a band, and this is what the feature turns on. Memory
Used is app plus wired plus compressed, so stacking it counts those three a
second time and puts the top of the card at nearly twice the RAM in the machine.
It keeps its line instead, landing exactly on the bands it sums. Swap keeps a
line too, being on disk rather than in RAM.

The claim is held against the real machine rather than a fixture: the slices
account for between 85% and 102% of physical RAM, so they cannot overlap, and
Used is strictly larger than any one of them. CPU is checked as the exact
identity it is.

Lines among bands are dashed, with a hollow legend swatch rather than a filled
one. A line on a stacked card is a different kind of statement -- a sum of the
bands under it, or something not in the whole at all -- and drawn in the same
solid stroke the card uses for slices it invites reading as one more slice.

A stacked card is bounded by the summed height per timestamp, not by its tallest
band: the top of the stack is what the eye reads. Stacked and mirrored are
exclusive, by declaration and again in ChartCard, because a band below a
baseline would be nonsense however it got there.

Closes #24

Claude-Session: https://claude.ai/code/session_01UPbN2SqYq8t2vcx2YWQTcs
@evandhoffman evandhoffman added the release:minor Merging this bumps the minor version label Aug 19, 2026
@evandhoffman
evandhoffman merged commit 492a442 into main Aug 19, 2026
2 checks passed
@evandhoffman
evandhoffman deleted the feat/issue-24-stacked-parts branch August 19, 2026 03:45
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

release:minor Merging this bumps the minor version

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Stack the memory chart

1 participant