Estou tentando criar um BarChart que mostre dois conjuntos de dados lado a lado: os valores atuais e os valores médios. Não importa o que eu tente, as barras sempre ficam empilhadas.
De acordo com todas as informações que encontrei, isso deveria ser possível usando .foregroundStyle(by: .value(...))
and/or .position(by: .value(...))
. No entanto, isso não tem efeito aqui.
Para começar, eu ficaria feliz em colocar as barras lado a lado. O objetivo final seria colocar as barras médias ligeiramente deslocadas atrás das barras atuais.
import SwiftUI
import Charts
struct ContentView: View {
let currentData: [DayData] = (1...15).map { DayData(day: $0, value: Double.random(in: 20...100)) }
let averageData: [DayData] = (1...15).map { DayData(day: $0, value: Double.random(in: 50...70)) }
var body: some View {
Chart {
ForEach(currentData) { day in
BarMark(
x: .value("Day", day.day),
y: .value("Current", day.value)
)
.foregroundStyle(by: .value("Data Type", "Current"))
.position(by: .value("Data Type", "Current"))
}
ForEach(averageData) { day in
BarMark(
x: .value("Day", day.day),
y: .value("Average", day.value)
)
.foregroundStyle(by: .value("Data Type", "Average"))
.position(by: .value("Data Type", "Average"))
}
}
.frame(height: 300)
.padding()
.chartXAxis {
AxisMarks(values: currentData.map { $0.day }) { _ in
AxisTick()
AxisGridLine()
AxisValueLabel()
}
}
}
}
// Datensatz für einen Tag
struct DayData: Identifiable {
let id = UUID()
let day: Int
let value: Double
}
#Preview {
ContentView()
}
Isso ocorre porque o eixo X do seu gráfico contém dados numéricos, não dados categóricos (strings).
Se você escrever
x: .value("Day", "\(day.day)")
em vez disso, as barras ficarão lado a lado como você espera. Como esses são dados categóricos, você não precisa passar explicitamente todos os rótulos x paraAxisMarks
nenhum deles.Se quiser manter os dados numéricos, você precisa especificar a
width:
para as barras e também passar os parâmetrosaxis
e de , porque o SwiftUI não consegue descobrir isso automaticamente para dados numéricos.span
position(by:)
Aqui, eu fiz a largura de cada barra um pouco maior que a metade do
span
, e configurei as barras médias para um z-index menor. Eu assumo que é isso que você quer dizer quando diz que quer que as barras médias fiquem "atrás" das barras atuais.Os valores que você passa para
width
espan
não precisam ser números simples. Eles sãoMarkDimension
s. Leia a documentação para saber mais sobre o que você pode fazer com eles.