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) }) } }
关键说明:
- 优化时间计算:一次性获取
dateComponents,避免重复调用,同时用?? 0处理可选值,规避强制解包的风险。 - 自定义Y轴刻度:通过
chartYAxis修饰符,利用AxisMarks遍历每个刻度值,将分钟数转换为HH:mm格式的字符串作为轴标签显示。 - 保留平滑曲线:依然以总分钟数作为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
相关产品推荐
相关产品推荐

