如何调整SwiftUI Chart中的网格线数量?
问题:调整SwiftUI Chart的网格线数量与标签显示
我正尝试调整(减少)SwiftUI Chart中的网格线数量,现有代码如下:
Chart() { ForEach(self.viewModel.downloadHistory) { item in LineMark(x: .value(String.empty, item.timestamp), y: .value(String.empty, item.value.floatValue)) .interpolationMethod(.stepCenter) .foregroundStyle(Colors.download) } } .chartXAxis(.hidden) .frame(height: 64.0) .gridColumnAlignment(.center) .chartYAxis() { AxisMarks() { value in AxisGridLine(centered: true, stroke: StrokeStyle(dash: [4.0, 4.0])) AxisValueLabel() { if let value = value.as(UInt64.self) { Text(DiskUtilities.toSpeedNoComma(value)) } } } } .padding()
当前生成的图表标签过多,希望实现以下两种方案之一:
- 减少网格线数量;
- 仅在0%、50%、100%对应的线条上显示文本。
请问这两种方案是否可行?
两种方案均可行,具体实现如下:
方案1:减少网格线数量
通过给AxisMarks指定position参数,控制自动生成的刻度数量,就能直接减少网格线和标签的数量。比如设置期望的刻度数为3,代码修改如下:
.chartYAxis() { // 指定期望生成的刻度数量,自动调整网格线密度 AxisMarks(position: .automatic(desiredCount: 3)) { value in AxisGridLine(centered: true, stroke: StrokeStyle(dash: [4.0, 4.0])) AxisValueLabel() { if let value = value.as(UInt64.self) { Text(DiskUtilities.toSpeedNoComma(value)) } } } }
你可以根据需求调整desiredCount的数值,SwiftUI会自动适配Y轴的取值范围生成对应数量的刻度。
方案2:仅在0%、50%、100%位置显示文本
首先需要获取Y轴的最大值,然后计算0、最大值的一半、最大值这三个关键刻度,再手动指定这些刻度来控制标签显示。假设你的downloadHistory中value.floatValue的最大值可以通过viewModel获取,代码示例如下:
// 先获取Y轴最大值 let maxValue = viewModel.downloadHistory.map { $0.value.floatValue }.max() ?? 0 let midValue = maxValue / 2 Chart() { // 原有LineMark代码不变 ForEach(self.viewModel.downloadHistory) { item in LineMark(x: .value(String.empty, item.timestamp), y: .value(String.empty, item.value.floatValue)) .interpolationMethod(.stepCenter) .foregroundStyle(Colors.download) } } .chartXAxis(.hidden) .frame(height: 64.0) .gridColumnAlignment(.center) .chartYAxis() { // 手动指定要显示的刻度值:0、midValue、maxValue AxisMarks(values: [0, midValue, maxValue]) { value in // 网格线正常显示 AxisGridLine(centered: true, stroke: StrokeStyle(dash: [4.0, 4.0])) AxisValueLabel() { if let value = value.as(UInt64.self) { Text(DiskUtilities.toSpeedNoComma(value)) } } } } .padding()
如果需要保留所有网格线但只在这三个位置显示文本,可以在AxisValueLabel里添加判断逻辑:
AxisValueLabel() { if let value = value.as(UInt64.self), [UInt64(0), UInt64(midValue), UInt64(maxValue)].contains(value) { Text(DiskUtilities.toSpeedNoComma(value)) } }
这样就能实现仅在0%、50%、100%对应的线条上显示文本,其他位置隐藏标签。
内容的提问来源于stack exchange,提问作者inexcitus
相关产品推荐
相关产品推荐

