iOS-图表库:不显示没有支持数据的 x 轴标签
iOS-Charts Library: x-axis labels without backing data not showing
我正在使用 iOS 的流行图表库 3.1.1 版。我 运行 遇到 x 轴标签问题,我似乎无法在网上找到答案:
假设我想要一个图表,一周中的每一天都有一个 x 轴标签(即:S、M、T、W、T、F、S)。我读过的很多论坛都建议采用在 x 轴上设置自定义值格式化程序的方法,如下所示:https://github.com/danielgindi/Charts/issues/1340
这适用于计算我有数据的日期的标签。我使用这种方法 运行 遇到的问题是,如果我没有特定日期的数据,则不会生成该日期的标签。
例如,如果我要使用如下所示的自定义值格式化程序:
public class CustomChartFormatter: NSObject, IAxisValueFormatter {
var days: = ["S", "M", "T", "W", "T", "F", "S"]
public func stringForValue(value: Double, axis: AxisBase?) -> String {
return days[Int(value)]
}
}
我的支持数据如下所示:[(0, 15.5), (1, 20.1), (6, 11.1)] 其中 0、1 和 6 代表天数,15.5、20.1 和11.1是那些天的数据点,那么当调用stringForValue
时,有些天永远不会为它们生成标签。
由于 value
始终基于该支持数据,因此在这种情况下它永远不会等于 2、3、4 或 5。因此,永远不会生成 "T"、"W"、"T" 和 "F" 的标签。
有谁知道如何强制库生成 7 个标签,一周中的每一天一个,而不管我的支持数据是什么?谢谢你。
首先,你这边有没有调试return days[Int(value)]
?从您的屏幕截图来看,很明显您的 value
after int cast 丢失了精度。例如2.1
和 2.7
将是 2
,它总是显示 T
。你得先看看你的value
。
如果您确定始终只有 7 个 x 轴标签,一个棘手的方法是强制 computeAxisValues
始终具有 [0,1,2,3,4,5,6] .
意思是,你确保你的数据x范围是[1,7](或[0,6]),在@objc open func computeAxisValues(min: Double, max: Double)
中,你应该可以看到min
是1 max
是 7。
然后你重写这个方法把axis.entries = [Double]()
设置为[0,1,2,3,4,5,6],没有任何计算。这应该为您提供正确的映射。
但是,在执行此操作之前,我建议您先花一些时间调试此方法,以了解您没有获得预期值的原因。
好的,多亏了@wingzero 的评论,我才能够让它工作。有几件事情需要这样做。为了简单起见,我将解释如何让 "days of the week" 标签按照我最初的要求工作。但是,如果您遵循这些步骤,您应该能够调整它们以按照您喜欢的方式格式化您的图表(例如,一年中的几个月)。
1) 确保设置图表的 x 轴最小值和最大值。在这种情况下,您会想说:chartView.xAxis.axisMinimum = 0.0
和 chartView.axisMaximum = 6.0
。这对第 2 步很重要。
2) 正如 Wingzero 所暗示的,创建一个 XAxisRenderer
的子类,它允许我们获取在第一步中设置的最小值和最大值,并确定应将哪些值传递给我们的 IAxisValueFormatter
子类在第三步。在这种情况下:
class XAxisWeekRenderer: XAxisRenderer {
override func computeAxis(min: Double, max: Double, inverted: Bool) {
axis?.entries = [0, 1, 2, 3, 4, 5, 6]
}
}
确保像这样将此渲染器传递给您的图表:chartView.xAxisRenderer = XAxisWeekRenderer()
3) 创建一个 IAxisValueFormatter
的子类,它采用我们在第二步中传递给图表的值 ([0, 1, 2, 3, 4, 5, 6]) 并获取相应的标签名称.这就是我在这里的原始问题中所做的。回顾一下:
public class CustomChartFormatter: NSObject, IAxisValueFormatter {
var days: = ["S", "M", "T", "W", "T", "F", "S"]
public func stringForValue(value: Double, axis: AxisBase?) -> String {
return days[Int(value)]
}
}
4) 将图表上的 labelCount
设置为等于您想要的标签数。在这种情况下,它将是 7。我将在此处的最后一步下面展示如何执行此操作以及其余步骤。
5) 强制启用标签
6) 在图表上强制启用粒度并将粒度设置为 1。据我了解,将粒度设置为 1 意味着如果您的图表传递给 stringForValue
的数据不是整数, 图表基本上会四舍五入所述数据或将其视为四舍五入。这很重要,因为如果您传入 0.5,您的 stringForValue
可能无法为您的标签生成正确的字符串。
7) 将 xAxis 上的值格式化程序设置为您在步骤 3 中创建的自定义格式化程序。
步骤 4-7(加上设置在步骤 3 中创建的格式化程序)如下所示:
chartView.xAxis.labelCount = 7
chartView.xAxis.forceLabelsEnabled = true
chartView.xAxis.granularityEnabled = true
chartView.xAxis.granularity = 1
chartView.xAxis.valueFormatter = CustomChartFormatter()
我正在使用 iOS 的流行图表库 3.1.1 版。我 运行 遇到 x 轴标签问题,我似乎无法在网上找到答案:
假设我想要一个图表,一周中的每一天都有一个 x 轴标签(即:S、M、T、W、T、F、S)。我读过的很多论坛都建议采用在 x 轴上设置自定义值格式化程序的方法,如下所示:https://github.com/danielgindi/Charts/issues/1340
这适用于计算我有数据的日期的标签。我使用这种方法 运行 遇到的问题是,如果我没有特定日期的数据,则不会生成该日期的标签。
例如,如果我要使用如下所示的自定义值格式化程序:
public class CustomChartFormatter: NSObject, IAxisValueFormatter {
var days: = ["S", "M", "T", "W", "T", "F", "S"]
public func stringForValue(value: Double, axis: AxisBase?) -> String {
return days[Int(value)]
}
}
我的支持数据如下所示:[(0, 15.5), (1, 20.1), (6, 11.1)] 其中 0、1 和 6 代表天数,15.5、20.1 和11.1是那些天的数据点,那么当调用stringForValue
时,有些天永远不会为它们生成标签。
由于 value
始终基于该支持数据,因此在这种情况下它永远不会等于 2、3、4 或 5。因此,永远不会生成 "T"、"W"、"T" 和 "F" 的标签。
有谁知道如何强制库生成 7 个标签,一周中的每一天一个,而不管我的支持数据是什么?谢谢你。
首先,你这边有没有调试return days[Int(value)]
?从您的屏幕截图来看,很明显您的 value
after int cast 丢失了精度。例如2.1
和 2.7
将是 2
,它总是显示 T
。你得先看看你的value
。
如果您确定始终只有 7 个 x 轴标签,一个棘手的方法是强制 computeAxisValues
始终具有 [0,1,2,3,4,5,6] .
意思是,你确保你的数据x范围是[1,7](或[0,6]),在@objc open func computeAxisValues(min: Double, max: Double)
中,你应该可以看到min
是1 max
是 7。
然后你重写这个方法把axis.entries = [Double]()
设置为[0,1,2,3,4,5,6],没有任何计算。这应该为您提供正确的映射。
但是,在执行此操作之前,我建议您先花一些时间调试此方法,以了解您没有获得预期值的原因。
好的,多亏了@wingzero 的评论,我才能够让它工作。有几件事情需要这样做。为了简单起见,我将解释如何让 "days of the week" 标签按照我最初的要求工作。但是,如果您遵循这些步骤,您应该能够调整它们以按照您喜欢的方式格式化您的图表(例如,一年中的几个月)。
1) 确保设置图表的 x 轴最小值和最大值。在这种情况下,您会想说:chartView.xAxis.axisMinimum = 0.0
和 chartView.axisMaximum = 6.0
。这对第 2 步很重要。
2) 正如 Wingzero 所暗示的,创建一个 XAxisRenderer
的子类,它允许我们获取在第一步中设置的最小值和最大值,并确定应将哪些值传递给我们的 IAxisValueFormatter
子类在第三步。在这种情况下:
class XAxisWeekRenderer: XAxisRenderer {
override func computeAxis(min: Double, max: Double, inverted: Bool) {
axis?.entries = [0, 1, 2, 3, 4, 5, 6]
}
}
确保像这样将此渲染器传递给您的图表:chartView.xAxisRenderer = XAxisWeekRenderer()
3) 创建一个 IAxisValueFormatter
的子类,它采用我们在第二步中传递给图表的值 ([0, 1, 2, 3, 4, 5, 6]) 并获取相应的标签名称.这就是我在这里的原始问题中所做的。回顾一下:
public class CustomChartFormatter: NSObject, IAxisValueFormatter {
var days: = ["S", "M", "T", "W", "T", "F", "S"]
public func stringForValue(value: Double, axis: AxisBase?) -> String {
return days[Int(value)]
}
}
4) 将图表上的 labelCount
设置为等于您想要的标签数。在这种情况下,它将是 7。我将在此处的最后一步下面展示如何执行此操作以及其余步骤。
5) 强制启用标签
6) 在图表上强制启用粒度并将粒度设置为 1。据我了解,将粒度设置为 1 意味着如果您的图表传递给 stringForValue
的数据不是整数, 图表基本上会四舍五入所述数据或将其视为四舍五入。这很重要,因为如果您传入 0.5,您的 stringForValue
可能无法为您的标签生成正确的字符串。
7) 将 xAxis 上的值格式化程序设置为您在步骤 3 中创建的自定义格式化程序。
步骤 4-7(加上设置在步骤 3 中创建的格式化程序)如下所示:
chartView.xAxis.labelCount = 7
chartView.xAxis.forceLabelsEnabled = true
chartView.xAxis.granularityEnabled = true
chartView.xAxis.granularity = 1
chartView.xAxis.valueFormatter = CustomChartFormatter()