我正在尝试创建一个条形图,它并排显示两个数据集:当前值和平均值。无论我尝试什么,条形图总是堆积如山。
根据我发现的所有信息,这应该可以通过使用
.foregroundStyle(by: .value(...))
和/或 .position(by: .value(...))
来实现。然而,这在这里不起作用。
首先,我很乐意将这些条并排放置。最终目标是将平均条形图稍微偏移到当前条形图后面。
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()
}
这是因为图表的 X 轴是数值数据,而不是分类数据(字符串)。
如果您改为写
x: .value("Day", "\(day.day)")
,则条形图将如您所愿并排排列。由于这是分类数据,因此您也不需要显式地将所有 x 标签传递给 AxisMarks
。
如果你想保持数据的数值,你需要为条形指定一个
width:
,并传递 axis
的 span
和 position(by:)
参数,因为 SwiftUI 无法自动计算出这些数值数据。
ForEach(currentData) { day in
BarMark(
x: .value("Day", day.day),
// this example works for categorical data too if you prefer that
// x: .value("Day", "\(day.day)"),
y: .value("Current", day.value),
width: 12
)
.foregroundStyle(by: .value("Data Type", "Current"))
.position(by: .value("Data Type", "Current"), axis: .horizontal, span: 20)
}
ForEach(averageData) { day in
BarMark(
x: .value("Day", day.day),
y: .value("Average", day.value),
width: 12
)
.foregroundStyle(by: .value("Data Type", "Average"))
.position(by: .value("Data Type", "Average"), axis: .horizontal, span: 20)
}
.zIndex(-1)
在这里,我使每个条形的宽度略大于
span
的一半,并将平均条形设置为较低的 z-index。我认为这就是您说希望平均柱位于当前柱“后面”时的意思。
您传递给
width
和 span
的值不需要是简单的数字。他们是MarkDimension
。阅读文档以了解有关可以使用它们做什么的更多信息。