Creating line chart with multiple lines
Asked Answered
E

2

16

Looking over Apple Documentation I found a straightforward way of doing this provided your dataset is structured correctly (mine is not). I've been working with a CSV file containing rows structured as below:

PM2.5 data, PM10 data, DateTime
PM2.5 data, PM10 data, DateTime
...

And I've parsed each row into a Measurement object:

struct Measurement: Identifiable {
    var id: String // time of measurement 
    var pm25: Float
    var pm10: Float
}

I naively assumed I could just add multiple line marks as so (measurements is an array of Measurement objects):

            Chart(measurements){
                LineMark (
                    x: .value("Time", $0.id),
                    y: .value("PM2.5", $0.pm25)
                )
                
                LineMark (
                    x: .value("Time", $0.id),
                    y: .value("PM2.5", $0.pm10)
                )
            }

But this does not create multiple lines. Can anyone provide any suggestions on how to achieve this using Swift Charts in Swift UI? I found many solutions on Stack Overflow but they are for Swift 4 or older, nothing for SwiftUI.

Exegesis answered 20/10, 2022 at 2:25 Comment(0)
D
25

you could try this simple approach, using the series version of LineMark:

Chart(measurements) {
    LineMark(
        x: .value("Time", $0.id),
        y: .value("PM2.5", $0.pm25),
        series: .value("pm25", "A")  // <-- here
    ).foregroundStyle(.red)
    
    LineMark(
        x: .value("Time", $0.id),
        y: .value("PM1.0", $0.pm10),
        series: .value("pm10", "B")   // <-- here
    ).foregroundStyle(.green)
}
Disject answered 20/10, 2022 at 3:41 Comment(0)
K
3

Another approach is using .linestyle(by:) where the second string becomes a chart label and the lines are automatically given different stroke types.

    Chart(measurements){
        LineMark (
            x: .value("Time", $0.id),
            y: .value("PM2.5", $0.pm25)
        )
        .lineStyle(by: .value("Type", "PM2.5"))
        
        LineMark (
            x: .value("Time", $0.id),
            y: .value("PM2.5", $0.pm10)
        )
        .lineStyle(by: .value("Type", "PM1.0"))

The result looks like this:

enter image description here

This doesn't seem as customizable as the accepted answer. However, it's a simple solution if the default appearance is acceptable.

Klepht answered 30/4 at 16:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.