如何将不相关的数组添加到 iOS-charts 折线图中的数据点标签?
How to add unrelated array to Datapoint labels in an iOS-charts line chart?
我已阅读 但它没有回答我的问题。
我用 iOS 图表渲染了一个折线图,没有 x/y 轴标签,only datapoint labels, like this。此图表将图表的 ChartDataEntry 中的温度值显示为 Y,间隔为 0..
var temperaturevalues: [Double] = [47.0, 48.0, 49.0, 50.0, 51.0, 50.0, 49.0]
但是,我想向数据点标签添加一个不相关的时间数组,times[i] 与 i 处的 temperatureValues 匹配。
var times: [String] = ["7 AM", "8 AM", "11 AM", "2 PM", "5 PM", "8 PM", "11 PM"]
我在单独的 class 中扩展了 IValueFormatter,如下所示:
class ChartsFormatterToDegrees: IValueFormatter {
func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
return "\(Int(value))°"
}
但它只允许我使用 ChartDataEntry 中的值自定义数据点标签,该值是用于在折线图中绘制 Y 的温度值。我如何在 indexValue 中添加另一个数组,以便 dataPoints 标签显示为这样?
return """
\(Int(value))°
\(timesOfDay)
"""
这是我的图表方法:
private func setupChartView(temperatureValues: [Double], timesDataPoints: [String]) {
var tempDataEntries: [ChartDataEntry] = []
let chartsFormatterToDegrees = ChartsFormatterToDegrees(time: timeDataPoints)
for eachTemp in 0..<temperatureValues.count {
let tempEntry = ChartDataEntry(x: Double(eachTemp), y: temperatureValues[eachTemp])
tempDataEntries.append(tempEntry)
}
let lineChartDataSet = LineChartDataSet(entries: tempDataEntries, label: "nil")
lineChartDataSet.valueFormatter = chartsFormatterToDegrees
let chartData = LineChartData(dataSets: [lineChartDataSet])
chartData.addDataSet(lineChartDataSet)
lineChartView.data = chartData
}
据我所知,IValueFormatter 扩展只允许您修改用于绘制图表的值,而不是在索引处添加额外的字符串数组。当我尝试下面的操作时,它只在 dataSetIndex 处打印 timesOfDay,它只在所有数据点标签上打印 timesOfDay[0]
。
class ChartsFormatterToDegrees: IValueFormatter {
init(time: [String]) {
timesOfDay = time
}
var timesOfDay = [String]()
func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
return """
\(Int(value))°
\(timesOfDay[dataSetIndex])
"""
}
}
这是我最新的打印方法:
class ChartsFormatterToDegrees: IValueFormatter {
var timesOfDay = [String]()
var values = [Double]()
init(values: [Double], time: [String]) {
timesOfDay = time
//print(values, "are the values") //prints values correctly
}
func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
//print(value, "at", dataSetIndex) //prints as 37.0 at 0, 39.0 at 0, 40.0 at 0 etc
if let index = values.firstIndex(of: value) {
return "\(Int(value))° \(timesOfDay[index])"
}
let i = values.firstIndex(of: value)
//print(i as Any, "is index of where value shows up") //prints as nil is index of where value shows up for each i
return "\(Int(value))°"
}
}
你的假设不对。在IValueFormatter
中,可以为相应的值构造任意字符串。您只看到 value 或 timeOfDay 的原因是因为您正在使用 """
表示法构建 String
添加多行,而用于入口点的标签可能因此无法正确计算其大小。您应该如下创建 String
并查看您得到了什么
class ChartsFormatterToDegrees: IValueFormatter {
var timesOfDay = [String]()
var values = [Double]()
init(values: [Double], time: [String]) {
timesOfDay = time
values = values
}
func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
if let index = values.firstIndex(of: value) {
return "\(Int(value))° \(timesOfDay[index])"
}
return "\(Int(value))°"
}
}
我已阅读
我用 iOS 图表渲染了一个折线图,没有 x/y 轴标签,only datapoint labels, like this。此图表将图表的 ChartDataEntry 中的温度值显示为 Y,间隔为 0..
var temperaturevalues: [Double] = [47.0, 48.0, 49.0, 50.0, 51.0, 50.0, 49.0]
但是,我想向数据点标签添加一个不相关的时间数组,times[i] 与 i 处的 temperatureValues 匹配。
var times: [String] = ["7 AM", "8 AM", "11 AM", "2 PM", "5 PM", "8 PM", "11 PM"]
我在单独的 class 中扩展了 IValueFormatter,如下所示:
class ChartsFormatterToDegrees: IValueFormatter {
func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
return "\(Int(value))°"
}
但它只允许我使用 ChartDataEntry 中的值自定义数据点标签,该值是用于在折线图中绘制 Y 的温度值。我如何在 indexValue 中添加另一个数组,以便 dataPoints 标签显示为这样?
return """
\(Int(value))°
\(timesOfDay)
"""
这是我的图表方法:
private func setupChartView(temperatureValues: [Double], timesDataPoints: [String]) {
var tempDataEntries: [ChartDataEntry] = []
let chartsFormatterToDegrees = ChartsFormatterToDegrees(time: timeDataPoints)
for eachTemp in 0..<temperatureValues.count {
let tempEntry = ChartDataEntry(x: Double(eachTemp), y: temperatureValues[eachTemp])
tempDataEntries.append(tempEntry)
}
let lineChartDataSet = LineChartDataSet(entries: tempDataEntries, label: "nil")
lineChartDataSet.valueFormatter = chartsFormatterToDegrees
let chartData = LineChartData(dataSets: [lineChartDataSet])
chartData.addDataSet(lineChartDataSet)
lineChartView.data = chartData
}
据我所知,IValueFormatter 扩展只允许您修改用于绘制图表的值,而不是在索引处添加额外的字符串数组。当我尝试下面的操作时,它只在 dataSetIndex 处打印 timesOfDay,它只在所有数据点标签上打印 timesOfDay[0]
。
class ChartsFormatterToDegrees: IValueFormatter {
init(time: [String]) {
timesOfDay = time
}
var timesOfDay = [String]()
func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
return """
\(Int(value))°
\(timesOfDay[dataSetIndex])
"""
}
}
这是我最新的打印方法:
class ChartsFormatterToDegrees: IValueFormatter {
var timesOfDay = [String]()
var values = [Double]()
init(values: [Double], time: [String]) {
timesOfDay = time
//print(values, "are the values") //prints values correctly
}
func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
//print(value, "at", dataSetIndex) //prints as 37.0 at 0, 39.0 at 0, 40.0 at 0 etc
if let index = values.firstIndex(of: value) {
return "\(Int(value))° \(timesOfDay[index])"
}
let i = values.firstIndex(of: value)
//print(i as Any, "is index of where value shows up") //prints as nil is index of where value shows up for each i
return "\(Int(value))°"
}
}
你的假设不对。在IValueFormatter
中,可以为相应的值构造任意字符串。您只看到 value 或 timeOfDay 的原因是因为您正在使用 """
表示法构建 String
添加多行,而用于入口点的标签可能因此无法正确计算其大小。您应该如下创建 String
并查看您得到了什么
class ChartsFormatterToDegrees: IValueFormatter {
var timesOfDay = [String]()
var values = [Double]()
init(values: [Double], time: [String]) {
timesOfDay = time
values = values
}
func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
if let index = values.firstIndex(of: value) {
return "\(Int(value))° \(timesOfDay[index])"
}
return "\(Int(value))°"
}
}