Skip to content

Chart Selection (SwiftUI)

A SwiftUI guide for coding agents. Also covers chartxselection, tap chart value ios, chart scrubbing, rulemark annotation, chart range selection, chartgesture.

iOS 17 gives Swift Charts one-line selection: chartXSelection and chartYSelection bind the value or range under the user's finger. Before that, selection meant hand-rolling a chartOverlay with a drag gesture and ChartProxy math.

One-Line Selection

Bind an optional value; the framework writes the selected chart value into it. Render feedback yourself, for example a RuleMark with an annotation.

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

    if let selectedIndex {
        RuleMark(x: .value("Index", selectedIndex))
            .annotation(position: .bottom) {
                Text(verbatim: selectedIndex.formatted())
                    .padding()
                    .background(.regularMaterial)
            }
    }
}
.chartXSelection(value: $selectedIndex)

Range Selection

The same modifiers accept a ClosedRange binding. A RectangleMark between the bounds is the usual highlight.

@State private var selectedRange: ClosedRange<Int>?

Chart { /* marks */
    if let selectedRange {
        RectangleMark(
            xStart: .value("Index", selectedRange.lowerBound),
            xEnd: .value("Index", selectedRange.upperBound),
            yStart: .value("Number", 0),
            yEnd: .value("Number", 10)
        )
        .foregroundStyle(.blue.opacity(0.03))
    }
}
.chartXSelection(range: $selectedRange)

Custom Gesture

chartGesture replaces the built-in gesture. It hands you the ChartProxy, so you can tune the DragGesture (a minimum distance, for example) and drive selection through selectXRange(from:to:).

.chartGesture { chart in
    DragGesture(minimumDistance: 16)
        .onChanged {
            chart.selectXRange(from: $0.startLocation.x, to: $0.location.x)
        }
        .onEnded { _ in selectedRange = nil }
}

On iOS 16, the fallback is chartOverlay: a near-transparent rectangle with a drag gesture, converting the touch x through chart.value(atX:) after subtracting the plot frame origin.

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-selection" })
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