Skip to content

Chart Scrolling (SwiftUI)

A SwiftUI guide for coding agents. Also covers scrollable chart ios, chartscrollableaxes, chartxvisibledomain, chart paging, chartscrollposition binding, date aligned chart snapping.

iOS 17 lets any Swift Charts chart scroll. chartScrollableAxes turns it on, the visible-domain modifiers set the window size, and chartScrollTargetBehavior controls snapping.

Making a Chart Scroll

Enable an axis, then cap how much data is visible at once with chartXVisibleDomain (or chartYVisibleDomain for vertical scrolling).

Chart(Array(zip(numbers.indices, numbers)), id: \.1) { index, number in
    LineMark(
        x: .value("Index", index),
        y: .value("Number", number)
    )
}
.chartScrollableAxes(.horizontal)
.chartXVisibleDomain(length: 10)

Scroll Position

chartScrollPosition(initialX:) sets where the chart starts. The binding overload reads and writes: the binding updates as the user scrolls, and setting it programmatically moves the visible region.

@State private var scrollPosition = 50

Chart { /* ... */ }
    .chartScrollableAxes(.horizontal)
    .chartScrollPosition(x: $scrollPosition)
    .onChange(of: scrollPosition) { print(scrollPosition) }

Snapping Behavior

chartScrollTargetBehavior(.valueAligned(...)) snaps the scroll to data values. The unit sets the minor snap step; majorAlignment decides where a full swipe lands, .page for one visible region, or .unit(10) for a value step.

.chartScrollTargetBehavior(
    .valueAligned(unit: 5, majorAlignment: .page)
)

Date axes align with DateComponents instead of numbers, for example snapping to hours while a swipe jumps by days.

Chart(data) { item in
    LineMark(
        x: .value("Date", item.date, unit: .day),
        y: .value("Value", item.value)
    )
}
.chartScrollableAxes(.horizontal)
.chartScrollTargetBehavior(
    .valueAligned(
        matching: DateComponents(minute: 0),
        majorAlignment: .matching(DateComponents(hour: 0))
    )
)

Custom behaviors conform to ChartScrollTargetBehavior, the chart-flavored sibling of the ScrollTargetBehavior protocol covered in the scrollview-target-behavior doc.

Use this guidance in your coding agent

Install the Better Design MCP once. Your agent then loads this page with one call.

get-swiftui-guide({ topic: "swiftui-mastering-charts-scrolling" })
claude mcp add --scope user better-design --transport http https://better-design.com/api/mcp --header "Authorization: Bearer <YOUR_API_KEY>"
Browse related design systems