Search code examples
chartsswift3alignmentnsdateios-charts

iOS Charts 3 - Align X Labels (dates) with plots


I have found a similar question on here, but the answer did not help me. I think due to my data structure.

I have an array made up of individual arrays, each for its own line in the chart. this is then made up of multiple structs for the plot points of that line.

My issue is that values/lines are correct, but are not aligning correctly with the dates. In the example below. the dates start at 3rd May and end 8th May. Please help

here is my code

struct chartPoint {
let date:String
var total:Double
let exercise:String
}
 var sets:[[chartPoint]] = []

func setupLineChart() {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "yyyy-MM-dd"
    var dataSets:[LineChartDataSet] = []
    var color:[UIColor] = [UIColor.red,UIColor.blue, UIColor.green,UIColor.red,UIColor.red,UIColor.red,UIColor.red]
    for i in sets { //Array of array of structs
        let sort = i.sorted { // sort the internal array by date
            item1, item2 in
            let date1 = dateFormatter.date(from:item1.date)
            let date2 =  dateFormatter.date(from:item2.date)
            return date1!.compare(date2!) == ComparisonResult.orderedAscending
        }
        var dataEntries: [ChartDataEntry] = []
        for stat in 0...(sort.count - 1) {
            let date = dateFormatter.date(from:sort[stat].date)
            let timeIntervalForDate: TimeInterval = date!.timeIntervalSince1970
            let dataEntry = ChartDataEntry(x: Double(timeIntervalForDate), y: sort[stat].total)
            dataEntries.append(dataEntry)
            if stat == (sort.count - 1){
                let chartDataSet = LineChartDataSet(values: dataEntries, label: "\(sort[stat].exercise)")
                chartDataSet.setCircleColor(color[stat])
                chartDataSet.setColor(color[stat], alpha: 1.0)

                chartDataSet.drawValuesEnabled = true
                dataSets.append(chartDataSet)
                startChart(dataSets: dataSets)
            }
        }
    }

}

func startChart(dataSets:[LineChartDataSet]){
    testLineChartView.animate(xAxisDuration: 0.7, yAxisDuration: 0.7)
    testLineChartView.dragEnabled = true
    testLineChartView.legend.form = .circle
    testLineChartView.drawGridBackgroundEnabled = false

    let xaxis = testLineChartView.xAxis
    xaxis.valueFormatter = axisFormatDelegate
    xaxis.labelCount = dataSets.count
    xaxis.granularityEnabled = true
    xaxis.granularity = 1.0
    xaxis.centerAxisLabelsEnabled = true
    xaxis.avoidFirstLastClippingEnabled = true
    xaxis.drawLimitLinesBehindDataEnabled = true

    let rightAxis = testLineChartView.rightAxis
    rightAxis.enabled = false

    let leftAxis = testLineChartView.leftAxis
    leftAxis.drawZeroLineEnabled = true
    leftAxis.drawGridLinesEnabled = true
    axisFormatDelegate = self
    testLineChartView.delegate = self

    let chartData = LineChartData(dataSets: dataSets)
    testLineChartView.data = chartData
    testLineChartView.chartDescription?.text = ""
}

extension ChartViewController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "dd MMM"
    let date = Date(timeIntervalSince1970: value)
    return dateFormatter.string(from: date)
}

}

enter image description here


Solution

  • I am using dates on the x-axis as well in one of my projects and I simply changed each date to a string and passed an array of string values to an IndexAxisValueFormatter.

     testLineChartView.xAxis.valueFormatter = IndexAxisValueFormatter(values: xvalues)
    

    If this is not what you are looking for, can you show a sample of what "sets" includes? Then I will be able to run your code.