You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

SwiftUI Charts:如何在Y轴绘制时分复合时间刻度

解决方案

你可以通过自定义Y轴的AxisMarks来实现将分钟数格式化为小时:分钟的显示效果,同时保持曲线的平滑性。以下是优化后的完整代码:

// 先定义需要的日期组件
let components: Set<Calendar.Component> = [.hour, .minute]

Chart {
    ForEach(sunriseSunset) { item in
        let timeComponents = Calendar.current.dateComponents(components, from: item.sunrise)
        let totalMinutes = (timeComponents.hour ?? 0) * 60 + (timeComponents.minute ?? 0)
        
        LineMark(
            x: .value("日期", item.sunrise),
            y: .value("时间", totalMinutes)
        )
    }
}
.chartYAxis {
    AxisMarks(position: .trailing) { value in
        // 将数值(分钟)转换回时间格式
        guard let totalMinutes = value.as(Int.self) else { return AxisGridLine() }
        let hours = totalMinutes / 60
        let minutes = totalMinutes % 60
        let formattedTime = String(format: "%02d:%02d", hours, minutes)
        
        return AxisTick()
            .foregroundStyle(.gray)
        + AxisGridLine()
            .foregroundStyle(.gray.opacity(0.3))
        + AxisLabel(content: {
            Text(formattedTime)
                .font(.caption)
        })
    }
}

关键说明:

  1. 优化时间计算:一次性获取dateComponents,避免重复调用,同时用?? 0处理可选值,规避强制解包的风险。
  2. 自定义Y轴刻度:通过chartYAxis修饰符,利用AxisMarks遍历每个刻度值,将分钟数转换为HH:mm格式的字符串作为轴标签显示。
  3. 保留平滑曲线:依然以总分钟数作为Y轴的数值基础,保证曲线的连续性,不会出现阶梯状。

如果希望Y轴刻度间隔更合理(比如每1小时或30分钟一个刻度),可以在AxisMarks中添加values参数指定:

AxisMarks(position: .trailing, values: .stride(by: 60)) { value in
    // 内部逻辑不变
}

这里的.stride(by: 60)表示每隔60分钟(1小时)显示一个刻度,可根据需求调整数值(比如30代表每30分钟)。

内容的提问来源于stack exchange,提问作者Edward Hasted

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 03:41:42