Swift ​Charts: ​Point​Mark annotation appears behind other ​Point​Marks

I’m using Swift Charts to show a scatter plot with multiple PointMarks. When the user selects a point, I attach an annotation to the selected PointMark to show a label like Strike 1.

I expected the annotation to render above all chart marks, but in practice nearby PointMarks can be drawn over the annotation text/background.

Simplified example:

Chart {
    ForEach(points.filter { !$0.isSelected }) { point in
        PointMark(
            x: .value("X", point.x),
            y: .value("Y", point.y)
        )
        .foregroundStyle(.black)
    }

    if let selectedPoint {
        PointMark(
            x: .value("X", selectedPoint.x),
            y: .value("Y", selectedPoint.y)
        )
        .foregroundStyle(.orange)
        .annotation(position: .top) {
            Text("Strike \(selectedPoint.number)")
                .padding(.horizontal, 8)
                .padding(.vertical, 4)
                .background(Capsule().fill(.orange.opacity(0.15)))
        }
    }
}

screenshots

Answered by DTS Engineer in 887658022

The good news is that your z-ordering approach is correct — filtering the selected point out of the ForEach and rendering it last does place the annotation in front of the other PointMarks. The visual overlap you're seeing is because the capsule background uses a low opacity (0.15), which allows the PointMarks underneath to remain visible.

If you increase the opacity of the capsule fill, the underlying points are visually occluded as you would expect:

.background(Capsule().fill(.orange.opacity(0.85)))

You can tune the value to whatever looks right for your design.

The good news is that your z-ordering approach is correct — filtering the selected point out of the ForEach and rendering it last does place the annotation in front of the other PointMarks. The visual overlap you're seeing is because the capsule background uses a low opacity (0.15), which allows the PointMarks underneath to remain visible.

If you increase the opacity of the capsule fill, the underlying points are visually occluded as you would expect:

.background(Capsule().fill(.orange.opacity(0.85)))

You can tune the value to whatever looks right for your design.

Hello sakrist,

Another workaround you can try is to use the Selections API to get the X/Y value and show the label as an overlay or popover over the entire Chart, rather than as an annotation. Please see WWDC 23: Explore pie charts and interactivity in Swift Charts.

Hoping this helps,

Richard Yeh  Developer Technical Support

Swift ​Charts: ​Point​Mark annotation appears behind other ​Point​Marks
 
 
Q