Docs
Data

Scrub Chart

A line or bar chart you scrub under a glass flag, hold to select a range, and switch with a glass picker that morphs the line.

$npx swiftpieces add ScrubChart
Free · MIT + Commons ClauseiOS 17.0+Liquid Glasschartlinebarsscrubrangemorphnumbers
Type
ScrubChart
Files
ScrubChart.swift
Depends on
Nothing (Apple frameworks only)
Version
2.2.1
In a full screen · SwiftPieces ProDashboardA home dashboard with a collapsing greeting, live metrics, a scrubbable chart and activity.

Time-series chart with scrubbing, range selection, and a morphing range picker. The chart is content; its chrome is liquid glass. A glass flag rides the scrub rule, and while a range is held the range's change buds out of the flag and rests joined to it. The range picker is a row of glass segments joined by liquid necks: the one you pick swells and takes the accent tint, which flows to it through the necks.

Notes

  • The readout is display type: an uppercase meta line (range, point time, or held span), a semibold 44 pt figure with its decimals dimmed, and a liquid glass delta chip beside it, tinted sage for up and red for down with ink text, and left clear with muted figures when nothing changed.
  • The figure is never cut short. Beside the chip it may shrink to 90% at most; when the widest figure and chip any range can show don't fit side by side at that size (a narrow card, a large figure, or a large Dynamic Type size), the chip sits under the figure instead, and only then does the figure scale down further, if it still can't fit on its own line. The choice is made once for the whole chart, across every range, so neither a scrub nor a range switch changes the readout's shape or moves the chart.
  • One finger drags to scrub: a rule and a butter dot sit on the nearest point, and a glass flag grows out of the top of the rule with its time. They move with the finger on the same frame and never ease after it, so the figure, the rule, the dot and the flag always agree, and .selection ticks at each point reached (not on release). Touching down brings the cursor in with the dot a beat ahead; letting go clears it and the flag sinks back into the rule. Holding still for 300 ms before moving pins the point under the finger as an anchor: the dot pops with a rigid tap and the drag becomes a range, a solid band fills the span and the figure shows the signed change with its percent. The range's change also buds out of the flag's side, on the side toward the middle of the plot, as a tinted glass chip that rests joined to the flag by a liquid neck; the flag keeps the pair inside the plot, and when the range ends the chip's tint drains and it melts back into the flag.
  • Figures roll straight to their new value when the mode changes (touch, pin, release, range switch), never counting through the values between and never overshooting, and change at once while you scrub. The delta chip's glass around them resizes with a little give, and its arrow blurs across when the direction turns.
  • Every series is normalized to 0...1 for drawing, so the y-scale never jumps between ranges. In .line mode datasets are resampled to 64 positions and switching ranges bends the line into the new one with no overshoot; the latest dot and the dashed baseline ride it, and the min and max labels leave at once and return once it lands. In .bars mode bars grow to their new heights and the active bar takes the accent block. New data in the same range morphs the same way without ending a scrub or a held range, and the min and max labels stay unless the min or max itself changed. When the chart goes from no data to data, on first appearance or when data loads later, the line unfolds from its baseline and bars rise from the floor, unhurried and without overshoot. A lazy list that rebuilds the row plays this again.
  • At rest: no y-axis, one dashed baseline at the first value, monospaced min and max markers that shift inward to stay inside the plot when the min or max is the first or last point (on the latest point they sit off its corner, clear of the dot), the latest point as a butter dot, and three uppercase date labels whose format follows the span of the range. The picker is a row of glass segments, 44 pt tall, joined by liquid necks: segments press in lightly, and the one you pick swells and takes the accent tint, which flows to it through the necks with a little give while the one it leaves narrows and drains back to clear glass. A range set through range from outside moves it the same way.
  • tint sets the line (the house text color by default). Style sets accent (also the picked segment's glass tint), up and down (the delta chips' glass tints), ink, muted, band, ground (the card the chart sits on), and numeralSize. format takes any FormatStyle from Double to String; deltas reuse it with a sign. range lets you own the picker index. An empty series shows "No data yet".
  • VoiceOver reads the readout and the plot as one element with the range, the latest value and change; swipe up or down steps the scrub point, and swiping up past the latest point lets it go. Each range segment is its own button, and the picked one reads as selected.
  • Under Reduce Motion the chart appears in place without unfolding, a range switch bends the line on a shorter spring, the picker's tint crossfades and its widths settle on a short spring with no give, the figures crossfade instead of rolling, the delta chip and the flag fade in without scaling, the range's change chip fades in beside the flag instead of budding, and a pinned anchor skips the pop but keeps its tap, band and readout change. Under Reduce Transparency the glass draws solid. Every string and symbol is semibold; size sets the hierarchy.
  • A full dashboard screen ships in SwiftPieces Pro (dashboard-screen).

Usage

ScrubChartExample().preferredColorScheme(.light)

Parameters

ParameterDescription
seriesOne dataset per range button, in display order. A single entry hides the picker.
mode.line draws a smoothed line with min and max markers; .bars draws one bar per point.
tintLine and bar color. Defaults to the style's line, the house text color.
formatNumber format for readouts, for example .number or .currency(code: "USD"). Defaults to .number.
rangeOptional binding to the selected series index, for driving the picker from outside.
styleAccent, delta, band, and numeral settings. Defaults to .standard: a butter accent, sage for up, red for down.

Install

Pick one. Run it from the folder that contains your .xcodeproj and the files land inside your app.

Terminal

$npx swiftpieces add ScrubChart

Or ask your coding agent · Claude Code, Cursor or Xcode, once the MCP server is connected

>Add the SwiftPieces "Scrub Chart" piece to my app

Or copy the source above into your app.

New to SwiftUI?If you know React, CSS or Tailwind, SwiftUI is easier to pick up than it looks.Try real app patterns first

Building a whole app? See SwiftPieces Pro →

All data and charts →

Build it yourself: SwiftUI animations guide

On this page

SwiftPiecesPro

Build the whole app with one library.

Production-ready screens, whole flows, complete app templates, a Build Kit your agent follows and Pro remixing.

54 screens · 46 patterns · 48 flows · 12 templates · 31 Build Kit skills

Explore Pro