Right here is an instance displaying two totally different knowledge units on the identical axis. It is advisable scale the info your self although, so on this instance I’ve completed so manually with the changes to the stress values, however you might additionally do that programatically.
Instance right here at github.com/jknlsn/MultipleDataSetSwiftChartsExample with lollipop element popover, and barely simplified instance beneath.
import Charts
import SwiftUI
import WeatherKit
struct HourWeatherStruct {
var date: Date
var stress: Double
var temperature: Double
var windSpeed: Double
}
let hours: [HourWeatherStruct] = [
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600),
pressure: 1015.0,
temperature: 18.2,
windSpeed: 6.1),
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600 * 2),
pressure: 1015.3,
temperature: 18.2,
windSpeed: 8.1),
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600 * 3),
pressure: 1015.9,
temperature: 18.2,
windSpeed: 9.4),
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600 * 4),
pressure: 1016.3,
temperature: 18.2,
windSpeed: 5.2),
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600 * 5),
pressure: 1016.3,
temperature: 18.2,
windSpeed: 12.1),
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600 * 6),
pressure: 1016.3,
temperature: 18.2,
windSpeed: 11.1),
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600 * 7),
pressure: 1017.3,
temperature: 18.2,
windSpeed: 10.1),
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600 * 8),
pressure: 1018.3,
temperature: 18.2,
windSpeed: 11.1),
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600 * 9),
pressure: 1018.3,
temperature: 18.2,
windSpeed: 9.1),
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600 * 10),
pressure: 1018.3,
temperature: 18.2,
windSpeed: 8.1),
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600 * 11),
pressure: 1017.3,
temperature: 18.2,
windSpeed: 19.9),
HourWeatherStruct(date: Date(timeIntervalSinceNow: 3600 * 12),
pressure: 1018.3,
temperature: 18.2,
windSpeed: 7.1),
]
struct InteractiveLollipopChartMinimal: View {
var physique: some View {
Chart {
ForEach(hours, id: .date) {
LineMark(
x: .worth("Date", $0.date, unit: .hour),
y: .worth("Wind Pace", $0.windSpeed)
)
.foregroundStyle(by: .worth("Worth", "Wind"))
LineMark(
x: .worth("Date", $0.date, unit: .hour),
y: .worth("Strain", ($0.stress - 1014) * 4)
)
.foregroundStyle(by: .worth("Worth", "Strain"))
}
.lineStyle(StrokeStyle(lineWidth: 4.0))
.interpolationMethod(.catmullRom)
}
.chartForegroundStyleScale([
"Pressure": .purple,
"Wind": .teal
])
.chartXAxis {
AxisMarks(place: .backside, values: .stride(by: .hour, depend: 2)) {
_ in
AxisTick()
AxisGridLine()
AxisValueLabel(format: .dateTime.hour(), centered: true)
}
}
.chartYAxis {
AxisMarks(place: .main, values: Array(stride(from: 0, by: 24, by: 4))){
axis in
AxisTick()
AxisGridLine()
AxisValueLabel("(1014 + (axis.index * 1))", centered: false)
}
AxisMarks(place: .trailing, values: Array(stride(from: 0, by: 24, by: 4))){
axis in
AxisTick()
AxisGridLine()
AxisValueLabel("(axis.index * 4)", centered: false)
}
}
}
}
struct InteractiveLollipopMinimal: View {
var physique: some View {
Record {
VStack(alignment: .main) {
VStack(alignment: .main) {
Textual content("Windspeed and Strain")
.font(.callout)
.foregroundStyle(.secondary)
Textual content("(hours.first?.date ?? Date(), format: .dateTime)")
.font(.title2.daring())
}
InteractiveLollipopChartMinimal()
.body(peak: 200)
}
.listRowSeparator(.hidden)
}
.listStyle(.plain)
.navigationBarTitle("Interactive Lollipop", displayMode: .inline)
}
}