4

I want to use the iOS16 Swift Charts to plot my data using the SF symbols with either symbol() or symbol(by:) modifiers. Currently, I'm using the SwiftUI view in place of the symbol - not as neat as I think it could be with symbols modifiers.

Here's my working code thus far:

import SwiftUI
import Charts

struct Vitals {
    var time: Int
    var pulse: Int
    
    init(time: Int, pulse: Int) {
        self.time = time
        self.pulse = pulse
    }
}

var data: [Vitals] = [
    Vitals(time: 5, pulse: 74),
    Vitals(time: 10, pulse: 68),
    Vitals(time: 15, pulse: 73),
    Vitals(time: 20, pulse: 78),
    Vitals(time: 25, pulse: 70),
    Vitals(time: 30, pulse: 69)
]

struct ContentView: View {
    var body: some View {
        Chart(data, id: \.time) {
            PointMark(
                x: .value("Time", $0.time),
                y: .value("Vitals", $0.pulse)
            )
            .annotation(position: .overlay, alignment: .center) {
                VStack(spacing: 4) {
                    Image(systemName: "apple.logo")
                }
            }
        }
        .chartYAxis() {
            AxisMarks(position: .leading)
        }
        .frame(height: 400)
        .padding(50)
        
    }
}
marc-medley
  • 8,931
  • 5
  • 60
  • 66
mgianzero
  • 87
  • 5

1 Answers1

1

The solution is as simple as this (use symbol(symbol:) instance method):

public func symbol(@ViewBuilder symbol: () -> View) -> some ChartContent

Here's the code:

import SwiftUI
import Charts

struct ContentView: View {
    var body: some View {
        Chart(data, id: \.time) {
            PointMark(x: .value("Time", $0.time),
                      y: .value("Vitals", $0.pulse)
            )
            .symbol {
                Image(systemName: "apple.logo")
                    .foregroundColor(.red)
            }
        }
        .chartYScale(domain: 0...120)
        .frame(height: 300)
        .padding(30)
    }
}

enter image description here

Andy Jazz
  • 49,178
  • 17
  • 136
  • 220