我正在尝试将轴单位标签添加到使用 Swift Charts 构建的图表中。
例如:
import SwiftUI
import Charts
struct ContentView: View {
struct ChartData: Identifiable {
var id: Double { xVal }
let xVal: Double
let yVal: Double
}
let data: [ChartData] = [
.init(xVal: -5, yVal: 5),
.init(xVal: 0, yVal: 10),
.init(xVal: 5, yVal: 20),
]
var body: some View {
Chart(data) {
LineMark(
x: .value("Position", $0.xVal),
y: .value("Height", $0.yVal)
)
}
.chartYAxis {
AxisMarks(position: .leading)
}
}
}
Run Code Online (Sandbox Code Playgroud)
我们如何创建像上面红色所示的轴标签 - 或者以其他方式向我们的轴添加单位/描述?
查看Apple文档,我发现了一种简单的方法来执行此操作,前提是您的数据集结构正确(我的数据集结构不正确)。我一直在使用一个 CSV 文件,其中包含结构如下的行:
PM2.5 data, PM10 data, DateTime
PM2.5 data, PM10 data, DateTime
...
Run Code Online (Sandbox Code Playgroud)
我已将每一行解析为一个Measurement对象:
struct Measurement: Identifiable {
var id: String // time of measurement
var pm25: Float
var pm10: Float
}
Run Code Online (Sandbox Code Playgroud)
我天真地认为我可以像这样添加多个线标记(measurements是一个对象数组Measurement):
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)
)
}
Run Code Online (Sandbox Code Playgroud)
但这不会创建多行。任何人都可以提供有关如何在 Swift UI 中使用 Swift Charts 实现此目标的任何建议吗?我在 Stack Overflow 上找到了很多解决方案,但它们适用于 Swift 4 或更早版本,没有适用于 SwiftUI。
我有一个 Swift 图表,可以在线条标记和条形标记之间切换。我已在每个标记的顶部添加注释以显示每个数据点的值。在条形图上,注释显示正确。但是,折线图上仅显示第一个注释。这是一个错误还是设计使然?
这是我用来在条形标记上显示注释的代码:
BarMark (
x: PlottableValue.value("Date", "\(day.name) \(day.date)") ,
y: PlottableValue.value("Miles", lookupDict[day] ?? 0)
)
.annotation {
if let miles = lookupDict[day] {
Text(verbatim: "\(miles)")
.font(.caption)
} else {
EmptyView()
}
}
Run Code Online (Sandbox Code Playgroud)
我在线条标记上使用了相同的注释修饰符块,但无法理解为什么它不能以相同的方式工作。
chartForegroundStyleScale在 Swift Charts 中,为每个数据系列设置 ShapeStyle 的签名是:
func chartForegroundStyleScale<DataValue, S>(_ mapping: KeyValuePairs<DataValue, S>) -> some View where DataValue : Plottable, S : ShapeStyle
Run Code Online (Sandbox Code Playgroud)
初始化程序KeyValuePairs( init(dictionaryLiteral: (Key, Value)...)) 仅采用可变参数,因此任何从数组初始化前景样式的尝试(在我的例子中<String, Color>)都会导致错误:
Cannot pass array of type '[(String, Color)]' as variadic arguments of type '(String, Color)'
Run Code Online (Sandbox Code Playgroud)
在我的应用程序中,图表系列的名称是根据数据动态设置的,因此尽管我可以生成[String : Color]字典或元组数组,(String, Color)但我看不到可以将其中任何一个传递到chartForegroundStyleScale? 除非我遗漏了一些东西,否则这似乎是 Swift 图表中的一个奇怪的限制,即系列名称需要为此修饰符进行硬编码?
我正在使用新的快速图表框架来显示一些数据。为了手动控制 x 轴 AxisValueLabels 的频率以及调整颜色,我实现了以下内容:
.chartXAxis {
AxisMarks(values: .automatic(desiredCount: 11, roundLowerBound: true, roundUpperBound: true)) { _ in
AxisGridLine(stroke: .init(lineWidth: 1)).foregroundStyle(Color.orange)
AxisValueLabel().foregroundStyle(Color.orange).font(.subheadline).offset(x: -10)
}
}
Run Code Online (Sandbox Code Playgroud)
我想显示每个 x 轴值的值(有 11 个点,但仅显示 10 个)。我已经尝试了无数的方法,但无法通过调整desiredCount参数来显示它应该显示的内容。将不胜感激在这件事上的任何帮助..
import Charts
import Foundation
import SwiftUI
struct FakeData: Codable {
var questionAndAnswers: [Int: Int]
var timePerQuestion: [Double]
var date: Date = .now
}
extension FakeData {
static let oneFakeInstance = FakeData(questionAndAnswers: [1875: 1875,
1890: 1890,
1980: 1980,
2112: 2112,
2726: 2726,
4088: 4088,
4284: 4284,
4784: 4784,
4800: 4800, …Run Code Online (Sandbox Code Playgroud) 我有这个非常简单的图表,没什么花哨的 - 只是占用股票指标价格并显示它们。
VStack {
Chart {
ForEach(viewmodel.chartData1) { chartData in
LineMark(x: .value("date", chartData.date),
y: .value("amount", chartData.close))
.interpolationMethod(.catmullRom)
AreaMark(x: .value("date", chartData.date),
y: .value("amount", chartData.close))
.interpolationMethod(.catmullRom)
}
}
.animation(.easeIn, value: viewmodel.chartData1.count)
.frame(height: 300)
.chartYScale(domain: viewmodel.range.0...viewmodel.range.1)
Spacer()
}
.padding(.horizontal, 16)
.task { await viewmodel.getSymbols() }
Run Code Online (Sandbox Code Playgroud)
如果我注释掉 AreaMarks - LineMark 将如我所料:

但是,当添加区域时它会中断:
有什么想法我在这里错过了什么吗?
是否可以使用 Apple 的新 SwiftUI 图表框架创建饼图/圆环图?
WWDC 视频中显示了饼图图像。任何有关如何创建饼图的帮助或代码示例将不胜感激。
我在 SwiftUI 应用程序中使用 Swift Charts 来制作折线图。我想旋转 Y 轴标签,使其从下到上读取。我尝试旋转文本,但旋转导致标签无法正确渲染。有没有办法旋转轴标签?
import SwiftUI
import Charts
struct ContentView: View {
struct Point: Identifiable {
let id = UUID()
let x: Float
let y: Float
}
let points = [
Point(x: 0, y: 1),
Point(x: 1, y: 4.5),
Point(x: 2, y: 3),
Point(x: 3, y: 6),
Point(x: 4, y: 7),
Point(x: 5, y: 5.2),
Point(x: 6, y: 9),
Point(x: 7, y: 12.5),
]
var body: some View {
Chart {
ForEach(points) { point in
LineMark( …Run Code Online (Sandbox Code Playgroud) 我创建了如下所示的图表视图。我想知道当用户点击栏时如何更改栏标记。
Chart {
ForEach(Data.lastOneHour, id: \.day) {
BarMark(
x: .value("Month", $0.day, unit: .hour),
y: .value("Duration", $0.duration)
)
}
}
Run Code Online (Sandbox Code Playgroud)
我看到.onTap修改器不可用BarMark,并且我看不到任何方法来访问条形标记并使用手势位置应用颜色GeometryReader。
我有一个图表,其中包含在 x 轴上跨越多天的WeatherKit.HourWeather对象。但是,我想排除夜间时间。看起来我可以使用 ChartXScale 修改器来做到这一点,如下所示:
let myDataSeperatedByHours = arrayWithAllDates.filter { ... }.sorted(...) // Array of WeatherKit.HourWeather objects filtered by isDaylight = true and sorted by date
let allDaytimeDates = myDataSeperatedByHours.map { $0.date } //only the Date objects
Chart {
ForEach(myDataSeperatedByHours, id: \.date) { hourData in
LineMark(
x: .value("hour", hourData.date),
y: .value("value", hourData.value)
)
}
}
.chartXAxis {
AxisMarks(position: .bottom, values: allDaytimeDates) { axisValue in
if let date = axisValue.as(Date.self) {
AxisValueLabel(
"\(Self.shortTimeFormatter.calendar.component(.hour, from: date))"
)
} …Run Code Online (Sandbox Code Playgroud)