Home > database >  How to add Strings on X-Axis in iOS-charts 4.0.3?
How to add Strings on X-Axis in iOS-charts 4.0.3?

Time:09-13

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 ))
  • Related