如何在 Swift 图表中标记轴?

hun*_*ley 19 swiftui swiftui-charts

我正在尝试将轴单位标签添加到使用 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)

图表输出,所需标签以红色注释: 在此输入图像描述

我们如何创建像上面红色所示的轴标签 - 或者以其他方式向我们的轴添加单位/描述?

hun*_*ley 20

这是正确的修饰符:

Chart {
    ...
}
.chartXAxisLabel("Position (meters)")
Run Code Online (Sandbox Code Playgroud)

您还可以提供如下所示的自定义视图:


Chart {
    ...
}
.chartXAxisLabel(position: .bottom, alignment: .center) {
    Text("Position (meters)")
}
Run Code Online (Sandbox Code Playgroud)


Mar*_*rcy 11

创建这些红色标签的一种方法是根据需要使用 Text 与 VStack 或 HStack 的组合。可以使用rotationEffect()旋转文本。这是经过修改的原始代码:

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 {
        HStack(alignment: .center, spacing: 0) {
            Text("Height(cm)")
                .rotationEffect(Angle(degrees: -90))
                .foregroundColor(.red)
            VStack {
                Chart(data) {
                    LineMark(
                        x: .value("Position", $0.xVal),
                        y: .value("Height", $0.yVal)
                    )
                }
                .chartYAxis {
                    AxisMarks(position: .leading)
                }
                Text("Position(meters)")
                    .foregroundColor(.red)
            }
        }
        .frame(width: 350, height: 400, alignment: .center)
    }
}
Run Code Online (Sandbox Code Playgroud)

这是最终的布局:

在此输入图像描述

使用 AxisMarks() 更改默认轴标记,包括标签、网格线和刻度线。在 AxisMarks 中,可以使用 AxisValueLabel() 分配各个轴标签。Text() 被格式化为 AxisValueLabel() 内容的单独标签。

使用 AxisMarks 时,默认网格线和刻度线会消失,因此已使用 AxisGridLine() 和 AxisTick() 将它们添加回来。应立即在 Chart{} 之后添加以下代码并替换原来的 .chartYAxis():

.chartXAxis {
    AxisMarks(position: .bottom, values: .automatic) { value in
        AxisGridLine(centered: true, stroke: StrokeStyle(dash: [1, 2]))
        AxisTick(centered: true, stroke: StrokeStyle(dash: [1, 2]))
        AxisValueLabel() {
            if let intValue = value.as(Int.self) {
                Text("\(intValue) m")
                    .font(.system(size: 10))
            }
        }
    }
}

.chartYAxis {
    AxisMarks(position: .leading, values: .automatic) { value in
        AxisGridLine(centered: true, stroke: StrokeStyle(lineWidth: 1))
        AxisValueLabel() {
            if let intValue = value.as(Int.self) {
                Text("\(intValue) cm")
                .font(.system(size: 10))
            }
        }
    }
} 
Run Code Online (Sandbox Code Playgroud)

带有自定义标签的图表将如下所示: 在此输入图像描述