I"m try to display two sets of data on a SwiftUI Charts Bar Graph. I want to bars to display side-by-side (i.e. blue-green, blue-green for the sample image). However, what I'm getting is the two sets of bars displayed separately as shown in the image. What am I doing wrong? Here's my code: The structure of the data isn't fixed, so it can change if necessary.
struct ContentView: View {
var body: some View {
let wheelDevelopmentArray = [
(chainring: "one", eff:[75, 69, 64, 60, 56, 53, 47, 43, 39, 36, 32]),
(chainring: "two", eff:[110, 101, 94, 88, 82, 77, 69, 63, 57, 53, 47])
]
Chart(wheelDevelopmentArray, id: \.chainring) { wheels in
ForEach(0..<wheels.eff.count, id: \.self) { i in
BarMark(
x: .value("gear", wheels.chainring),
y: .value("size", wheels.eff[i]),
width: 20
)
.foregroundStyle(by: .value("ChainRing", wheels.chainring))
.position(by: .value("ChainRing", i))
}
}
.chartXAxis {
AxisMarks (values: .stride (by: 1)) { value in
AxisValueLabel()
}
}
.padding()
}
}
Because the x values were defined as the chainring values of "one" and "two", the chart is displaying the "one"s first and then the "two"s.
To display the bars side by side, x values are needed that relate a "one" bar with a "two" bar. Since the arrays are the same size, the index works as an example:
BarMark(x: .value("gear", String(i)),
Side note - the x value is converted to a String to avoid the barmark from stacking. This might be a chart bug.
With the x values changed, the chartXAxis labels are no longer needed. Also change the .position value to the chainring type for side by side positioning:
.position(by: .value("ChainRing", wheels.chainring))
Modified code:
struct ContentView: View {
var body: some View {
let wheelDevelopmentArray = [
(chainring: "one", eff:[75, 69, 64, 60, 56, 53, 47, 43, 39, 36, 32]),
(chainring: "two", eff:[110, 101, 94, 88, 82, 77, 69, 63, 57, 53, 47])
]
Chart(wheelDevelopmentArray, id: \.chainring) { wheels in
ForEach(0..<wheels.eff.count, id: \.self) { i in
BarMark(
x: .value("gear", String(i)),
y: .value("size", wheels.eff[i]),
width: 20
)
.foregroundStyle(by: .value("ChainRing", wheels.chainring))
.position(by: .value("ChainRing", wheels.chainring))
}
}
.padding()
}
}