How to add Strings on X Axis in iOS-charts?

夙愿已清 提交于 2019-11-27 06:45:48
Julio Cesar Aguilar Jiménez

I found the solution, maybe another one can solve this problem in a better way, without create a new class, well this is what I found:

First you nedd to create a new class, which will be your formatter class and add the IAxisValueFormater interface, then you use the method stringForValue to customize the new values, it takes two parameters, the first is the actual value (you can see it like the index) and second is the axis where the value is.

import UIKit
import Foundation
import Charts

@objc(BarChartFormatter)
public class BarChartFormatter: NSObject, IAxisValueFormatter
{
  var months: [String]! = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]

  public func stringForValue(value: Double, axis: AxisBase?) -> String 
  {
    return months[Int(value)]
  }   
}

Now in your file at the begining of your setChart() function you have to create two variables one for your formatter class and one for the axis class:

let formato:BarChartFormatter = BarChartFormatter()
let xaxis:XAxis = XAxis()

Next, go ahead at the end of the for in loop and pass the index and axis to your formatter variable:

formato.stringForValue(Double(i), axis: xaxis)

After looping add the format to your axis variable:

xaxis.valueFormatter = formato

The final step is to add the new xaxisformatted to the barChartView:

barChartView.xAxis.valueFormatter = xaxis.valueFormatter

And that's all the other lines in the setChart() function just keep it where they are, I hope it can help you.

Harshit Goel

Hello recently I encountered the same problem and solved it this way-

class ViewController: UIViewController {

    var months: [String]!
    var unitsSold = [Double]()
    weak var axisFormatDelegate: IAxisValueFormatter?

    @IBOutlet var viewForChart: BarChartView!
    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
        axisFormatDelegate = self
        months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
        unitsSold = [20.0, 4.0, 6.0, 3.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0]

       // setChart(_ dataPoints:months,_ forY: unitsSold)
        setChart(dataEntryX: months, dataEntryY: unitsSold)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }

    func setChart(dataEntryX forX:[String],dataEntryY forY: [Double]) {
        viewForChart.noDataText = "You need to provide data for the chart."
        var dataEntries:[BarChartDataEntry] = []
        for i in 0..<forX.count{
           // print(forX[i])
           // let dataEntry = BarChartDataEntry(x: (forX[i] as NSString).doubleValue, y: Double(unitsSold[i]))
            let dataEntry = BarChartDataEntry(x: Double(i), y: Double(forY[i]) , data: months as AnyObject?)
            print(dataEntry)
            dataEntries.append(dataEntry)
        }
        let chartDataSet = BarChartDataSet(values: dataEntries, label: "Units Sold")
        let chartData = BarChartData(dataSet: chartDataSet)
        viewForChart.data = chartData
        let xAxisValue = viewForChart.xAxis
        xAxisValue.valueFormatter = axisFormatDelegate

    }
}

At the end simply add the extension for the delegate

extension ViewController: IAxisValueFormatter {

    func stringForValue(_ value: Double, axis: AxisBase?) -> String {
    return months[Int(value)]
    }
}

Figured this solution out through this link https://medium.com/@skoli/using-realm-and-charts-with-swift-3-in-ios-10-40c42e3838c0#.minfe6kuk

As many people said you can create a class or extend with the type IAxisValueFormatter, but you can easily use the following method which only take 3 lines :

self.chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in
    return xStrings[Int(index)]
})

here's my setChart() function in case some of you find some of my customization interesting :

func setChartView(entriesData: [entry]) {
    var chartEntries: [ChartDataEntry] = []
    var xStrings: [String] = []
    let sortedentriesData = entriesData.sorted { (s1: entry, s2: entry) -> Bool in
        return s1.timestamp < s2.timestamp
    }
    for (i, entry) in sortedentriesData.enumerated() {
        let newEntry = ChartDataEntry(x: Double(i), y: entry.temperature)
        chartEntries.append(newEntry)
        let dateFormatter = DateFormatter()
        dateFormatter.timeStyle = .medium
        dateFormatter.dateStyle = .none
        xStrings.append("\(dateFormatter.string(from: Date.init(timeIntervalSince1970: TimeInterval(entry.timestamp))))")
    }
    let set: LineChartDataSet = LineChartDataSet(values: chartEntries, label: "°C")
    set.setColor(NSUIColor.blue, alpha: CGFloat(1))
    set.circleColors = [NSUIColor.blue]
    set.circleRadius = 3
    set.mode = LineChartDataSet.Mode.cubicBezier

    let data: LineChartData = LineChartData(dataSet: set)
    self.chartView.xAxis.labelRotationAngle = -90
    self.chartView.xAxis.valueFormatter = DefaultAxisValueFormatter(block: {(index, _) in
        return xStrings[Int(index)]
    })
    self.chartView.xAxis.setLabelCount(xStrings.count, force: true)
    self.chartView.data = data
}

entry is a struct I created :

struct entry {
    var timestamp: Int
    var temperature: Double
}

A cleaner way to implement the suggestion above if you are subclassing a graph is to implement IAxisValueFormatter protocol in your subclass itself

class CustomGraphView : LineChartView, ChartViewDelegate, IAxisValueFormatter {}

like this...

public func stringForValue(_ value: Double, axis: Charts.AxisBase?) -> String
{
    return "My X Axis Label Str";  // Return you label string, from an array perhaps.
}

Then in your init()

self.xAxis.valueFormatter = self;

The most simple solution:

barChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: months)
barChartView.xAxis.granularity = 1
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!