它将一个人的睡眠分为4个类别:清醒、快速、核心和深度.我得到了我想要的图表,显示了晚上不同时间(每小时)的睡眠数据,但我不知道如何让我的Y轴以正确的顺序显示.我希望它被分成四个阶段,每个睡眠阶段,从最高清醒开始,在REM以下,在核心以下,在底部深度,图形高度的25%.然而,无论我try 什么,它都保持着秩序的核心,清醒,深沉,快速.我试过使用.chartYAxis,但它似乎没有任何作用.我可以在文档中看到如何针对数字或日期调整它,但对于我想要的,我非常困惑,特别是当我没有收到错误时,它只是无法默默地对它们进行排序.我想过以某种方式使用Integer来表示每种睡眠类型,0=唤醒,4=深度,并以某种方式将它们对应到字符串值,但我不确定如何实现这一点.谢谢你的帮助!

enum SleepType: String, Plottable, CaseIterable {
    case Awake
    case REM
    case Core
    case Deep
}

struct SingleSleep: Hashable, Identifiable {
    let id = UUID()
    let startDate: Date
    let stopDate: Date
    var sleepTime: TimeInterval = 0 //in minutes
    var sleepType: SleepType
}

struct SleepExampleView: View {
    
    var sleep = [
        SingleSleep(startDate: Date(timeIntervalSinceReferenceDate: 729208384), stopDate: Date(timeIntervalSinceReferenceDate: 729209374), sleepTime: 16.5, sleepType: .Core),
        SingleSleep(startDate: Date(timeIntervalSinceReferenceDate: 729209374), stopDate: Date(timeIntervalSinceReferenceDate: 729209404), sleepTime: 16.5, sleepType: .Awake),
        SingleSleep(startDate: Date(timeIntervalSinceReferenceDate: 729209404), stopDate: Date(timeIntervalSinceReferenceDate: 729209794), sleepTime: 16.5, sleepType: .Core),
        SingleSleep(startDate: Date(timeIntervalSinceReferenceDate: 729209794), stopDate: Date(timeIntervalSinceReferenceDate: 729211234), sleepTime: 16.5, sleepType: .Deep),
        SingleSleep(startDate: Date(timeIntervalSinceReferenceDate: 729211234), stopDate: Date(timeIntervalSinceReferenceDate: 729211864), sleepTime: 16.5, sleepType: .REM),
    ]
    
    var body: some View {
        //chart
        
        Chart {
            ForEach(sleep, id: \.self) { sleep in
                LineMark(
                    x: .value("Time", sleep.startDate),
                    y: .value("Type", sleep.sleepType.rawValue)
                )
            }
        }
        .chartYAxis {
            AxisMarks(
                values: [SleepType.Awake.rawValue, SleepType.REM.rawValue, SleepType.Core.rawValue, SleepType.Deep.rawValue]
              )
        }
        .chartXAxis {
            AxisMarks(values: .stride(by: .hour, count: 1)) { value in
                AxisValueLabel(format: .dateTime.hour(), centered: true)
            }
        }
        .frame(width: 300, height: 300)
        .preferredColorScheme(.dark)
        .background(.clear)
    }
}

推荐答案

Y值的顺序是关于domain的问题,而不是轴的问题.

您可以使用chartYScale将域修改为您想要的任何值集:

Chart {
    ForEach(sleep) { sleep in
        LineMark(
            x: .value("Time", sleep.startDate),
            y: .value("Type", sleep.sleepType)
        )
    }
}
.chartYScale(domain: .automatic(dataType: SleepType.self, modifyInferredDomain: { domain in
    // put your order here:
    domain = [SleepType.Awake, .REM, .Core, .Deep]
}))
// you don't need chartYAxis here since sleep type is discrete data
// the y axis shows all the values by default
.chartXAxis {
    AxisMarks(values: .stride(by: .hour, count: 1)) { value in
        AxisValueLabel(format: .dateTime.hour(), centered: true)
    }
}

请注意,我使用了SleepType个值本身来绘制y轴,而不是它们的rawValue.SleepTypePlottable是一致的.

Ios相关问答推荐

带外部笔划的圆形进度视图

SwiftUI绑定到特定的一个或多个枚举 case

自定义UIControl不适用于UITapGestureRecognizer

拖动手势导致 sim 崩溃 Swift UI

确保方法调配的安全有效实施

mapView swift 导致警告有网格错误

在自定义 ButtonStyle 中修改形状 colored颜色

在 SwiftUI 中放置全局 NavigationPath 的位置

从iOS键盘输入时Flutter TextField输入消失

VStack 显示错误实例方法 'sheet(item:onDismiss:content:)' 要求 'Int' 符合 'Identifiable'

SwiftUI 选项卡式视图防止滑动到下一个选项卡

Swift如何表示单位转换的标准大气压

辅助功能判断器无法在 macOS Monterey 版本 12.3 上的 Xcode 版本 13.3 上运行

Flutter 错误:CocoaPods not installed or not in valid state.

iOS 11 navigationItem.titleView 宽度未设置

Xcode 11 向后兼容性:UIWindowScene 仅在 iOS 13 或更高版本中可用

正确的领域使用模式/最佳实践?

关闭通过模态 segue 显示的视图

以编程方式创建按钮并设置背景图像

使用 swift 从应用程序委托打开视图控制器