I Stucked on my tryings to implement custom labels on xAxis in last update of ios Charts (4.0.3).
Have this code:
// some model inside with parsed JSON, this is working well.
var dataRad = [DataModel]()
var dataEntries = [BarChartDataEntry]()
for item in dataRad {
guard let level = Double(item.level!), let id = Double(item.id!) else { return }
let dataEntry = BarChartDataEntry(x: id, y: level)
// labels.append(item.temp!)
dataEntries.append(dataEntry)
}
// some setup of the Charts, e.g. colors etc.
let xAxis = chartsView.xAxis
xAxis.labelFont = UIFont(name:"Play-Bold", size:10)!
xAxis.labelPosition = .bottom
xAxis.labelCount = self.dataRad.count
xAxis.drawLabelsEnabled = true
let labels: [String] = ["1, 2", "2, 2", "3, 3", "4, 4", "5, 5", "6, 6", "7, 7", "8, 8", "9, 9", "10, 10"]
xAxis.valueFormatter = IndexAxisValueFormatter(values: labels)
This code doesn't work. I can't see labels on my xAxis. But if I delete this formatter, I see defaults values of my "id" var (in "for in" loop).
I've tried some tricks, like extensions, add. class with formatter. Nothing works for me...
Please help to solve this problem with labels. Thank you!
CodePudding user response:
Here is my current setup for Charts
let labelFont = UIFont.SFProText(style: .bold, ofSize: 12)
let lineWidth = CGFloat(1)
// Setup style for X axis
barChartView.xAxis.axisLineWidth = lineWidth
barChartView.xAxis.labelFont = labelFont
barChartView.xAxis.labelTextColor = .white
barChartView.xAxis.axisLineColor = .white
barChartView.xAxis.labelPosition = .bottom
barChartView.xAxis.drawAxisLineEnabled = true
barChartView.xAxis.drawLabelsEnabled = true
barChartView.xAxis.drawGridLinesEnabled = false
barChartView.xAxis.spaceMax = 0
barChartView.xAxis.spaceMin = 0
barChartView.xAxis.decimals = 0
barChartView.xAxis.granularity = 1
barChartView.xAxis.granularityEnabled = true
barChartView.xAxis.labelFont = labelFont
barChartView.xAxis.axisLineColor = .white
barChartView.xAxis.labelTextColor = .white
Then you can try my CustomIndexAxisFormatter
:
class CustomIndexAxisFormatter: NSObject, AxisValueFormatter {
private var _values: [(Double, String)] = [(Double, String)]()
private var _valueCount: Int = 0
public var values: [(Double, String)] {
get {
return _values
}
set {
_values = newValue
_valueCount = _values.count
}
}
public override init(){
super.init()
}
public init(values: [(Double, String)]) {
super.init()
self.values = values
}
public static func with(values: [(Double, String)]) -> CustomIndexAxisFormatter? {
return CustomIndexAxisFormatter(values: values)
}
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
if let firstIndex = self.values.firstIndex(where: { $0.0 == value }) {
return _values[firstIndex].1
}
if value <= 1000 && values.indices.contains(Int(value)) {
return _values[Int(value)].1
} else {
guard let axis = axis else {
return ""
}
let count = Double(self._valueCount)
let diff = value - axis.axisMinimum
let range = axis.axisRange
let step = range / (count - 1)
let index = Int(round(diff / step))
guard values.indices.contains(index) else { return "" }
return _values[index].1
}
}
}
Then when you make dataSet:
let labels: [String] = ["1, 2", "2, 2", "3, 3", "4, 4", "5, 5", "6, 6", "7, 7", "8, 8", "9, 9", "10, 10"]
var arrayXLabel: [(Double, String)] = []
for (index, item) in entries.enumerated() {
if index < labels.count - 1 {
// need to use item.x as Double value of Array label
// because we will need to link label with chart point properly
arrayXLabel.append((item.x, labels[index]))
}
}
barChartView.xAxis.valueFormatter = CustomIndexAxisFormatter(values: arrayXLabel ))