Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to Modify X Axis values Swift? #1340

Closed
ajimenezjulio opened this issue Aug 20, 2016 · 34 comments
Closed

How to Modify X Axis values Swift? #1340

ajimenezjulio opened this issue Aug 20, 2016 · 34 comments

Comments

@ajimenezjulio
Copy link

With the new release i had some troubles to create some graphs, the previous code was:

func setChart(dataPoints: [String], values: [Double]) {
var dataEntries: [BarChartDataEntry] = []

for i in 0..<dataPoints.count {
    let dataEntry = BarChartDataEntry(value: values[i], xIndex: i)
    dataEntries.append(dataEntry)
}

let chartDataSet = BarChartDataSet(yVals: dataEntries, label: "Units Sold")
let chartData = BarChartData(xVals: months, dataSet: chartDataSet)
barChartView.data = chartData
}

You can pass the values for example an array of months using the line:

let chartData = BarChartData(xVals: months, dataSet: chartDataSet)

After the new release the code to implement the same graph is:

func setChart(dataPoints: [String], values: [Double]) {

    var dataEntries: [BarChartDataEntry] = []

    for i in 0..<dataPoints.count {
        let dataEntry = BarChartDataEntry(x: Double(i+2), y:values[i], data: months )
        dataEntries.append(dataEntry)
    }

    let chartDataSet = BarChartDataSet(values: dataEntries, label: "Units Sold")

    let chartData = BarChartData()
    chartData.addDataSet(chartDataSet)
    barChartView.data = chartData

}

I was trying a few hours but i couldn't find a way to modify the X axis values, i hope someone can help me, thanks!!

@NyoSeintLay
Copy link

I modify x-axis value in scatter chart and it is working now.
I found 2 points :

1: let dataEntry = BarChartDataEntry(x: Double(i+2), y:values[i], data: months )
Use ChartDataEntry(x,y) instead of BarChartDataEntry method.

2: let chartData = BarChartData() -> let chartData = BarChartData(dataset)

Hope it can help you.

@ajimenezjulio
Copy link
Author

Thank you NyoSeint, you're right with your method you can modify x-axis but just in a numerical way, i'm trying to put Strings in this case months in x-axis

@liuxuan30
Copy link
Member

have you checked the ChartsDemo? I believe there are answers.

@seal62
Copy link

seal62 commented Aug 25, 2016

I am also looking for an answer to this, opened a case earlier here - #1331

Couldnt find an answer in the demos, please let me know if you find a solution. thanks

@ajimenezjulio
Copy link
Author

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.

@danielgindi
Copy link
Collaborator

@ajimenezjulio This is the indeed correct way :-)

We are using formatters now, due to independent x-values. This is of course less comfortable for those who used to have simplistic x-indexes array, but opens a whole world of possibilities. This removed the constraint of having to predefined the x-indexes with their labels.

I'm sure we'll come up with new ways of writing less code for simplistic situations like this, in the future.

@dante20007
Copy link

Please give us back an easy way to customize the xaxis.
The previous version was so nice for that ! (or at least a tutorial for both Swift/Objc)

Thx.

@dante20007
Copy link

Any update ?

@danielgindi
Copy link
Collaborator

@dante20007 Sorry, you can't have it all. People want to be able to add entries at any x-index, not just 0, 1, 2, but also 0, 1.3, 2.7... An array can't represent labels for such values.

@dante20007
Copy link

What if we want to have months displayed on the X axis ? not possible too ?

Thx.

@pdecarcer
Copy link

Hi I try to add this solution but when I move to the right it said index out of range, the I know I have just 12 month

@decaluwepatrick
Copy link

I also need an easy way to customize the x-axis.. I went back to the previous version of charts because of this.

@pdecarcer
Copy link

This is a easy way to customize my problem was that when I move to the right start to render again so I modify the lib and put to ignore if the index when render

@decaluwepatrick
Copy link

Sorry I was talking about "How to Modify X Axis values Swift?" using Strings

@pdecarcer
Copy link

Yes me too. I used same answer of @ajimenezjulio

@decaluwepatrick
Copy link

I am maintaining a project that is in Objective-C, and although I managed to reproduce the answer of @ajimenezjulio it would not compile: for some reason the IAxisValueFormatter was never recognized.

@AlexSmet
Copy link

I had a similar problem. Documentation is too short, but working with x Axis require some lines of code. Using the code provided by @ajimenezjulio I have made class extension for simplifying the use BarChartView. Maybe it will be useful for someone.

extension BarChartView {

    private class BarChartFormatter: NSObject, IAxisValueFormatter {
        
        var labels: [String] = []
        
        func stringForValue(_ value: Double, axis: AxisBase?) -> String {
            return labels[Int(value)]
        }
        
        init(labels: [String]) {
            super.init()
            self.labels = labels
        }
    }
    
    func setBarChartData(xValues: [String], yValues: [Double], label: String) {
        
        var dataEntries: [BarChartDataEntry] = []
        
        for i in 0..<yValues.count {
            let dataEntry = BarChartDataEntry(x: Double(i), y: yValues[i])
            dataEntries.append(dataEntry)
        }
        
        let chartDataSet = BarChartDataSet(values: dataEntries, label: label)
        let chartData = BarChartData(dataSet: chartDataSet)
        
        let chartFormatter = BarChartFormatter(labels: xValues)
        let xAxis = XAxis()
        xAxis.valueFormatter = chartFormatter
        self.xAxis.valueFormatter = xAxis.valueFormatter
        
        self.data = chartData
    }
} 

Usage

func setChart(){
        let months = ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"]
        let unitsSold = [20.0, 4.0, 3.0, 6.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0]
        
        barChartView.setBarChartData(xValues: months, yValues: unitsSold, label: "Monthly Sales")
    } 

@neerumehn
Copy link

Hey, can have other charts extension too?

@Frog1111
Copy link

I'm getting an error " BarChartFormatter does not conform to protocol IAxisValueFormatter.

Why did you do this? It was so easy to use in Android Studio. Does ANYONE know how to get an array ["J", "F", etc... into the X axis? I'm screwed here. These "examples are above my skill level.

@ReneVella
Copy link

Is there a solution for ObjC to format the X Axis with custom labels ?

@Aquima
Copy link

Aquima commented Dec 15, 2017

in YourViewControllerViewController declare var months: [String] = String and set values of month of you needed
extension YourViewControllerViewController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
return months[Int(value) % months.count]
}
}

@Krishnaprasad66
Copy link

Hi,
I tried to add the solution. But i am always getting an error 'index out of range'

@robotsquidward
Copy link

Yeah, I wish I understood more how stringForValue is called and how your customization of the chart/data changes how it gets called for your data. I did some of this checking to avoid the index out of range. Kind of a band-aid though 🤷‍♂️

       func stringForValue(_ value: Double, axis: AxisBase?) -> String {
            let index = Int(value)
            if index < labels.count && index >= 0 {
                return labels[index]
            } else {
                return ""
            }
        }

@fhatvirgo
Copy link

Open button

@jitccgcg
Copy link

@robotsquidward - Me too. It would be nice if the documentation explained how it worked or, better yet, one of the demos showed how to do it. I imagine there are a lot of people who need to use strings for labels but there's no clear explanation or example that I can find that would help. I just see a bunch of answers that say look at stringForValue(). Sigh...

@benzai
Copy link

benzai commented May 22, 2018

@AlexSmet
Thanks a lot for the extension! It works great. I'm using a line chart, so I modified the code a bit. It works, however I'm having a visual bug. Any idea why the days on the X axis are not aligned correctly? Also monday and wednesday are being displayed 2 times in a row.
See screenshot: https://imgur.com/a/OG7OuSY

dataContent1 = ["MON", "TUE", "WED", "THU", "FRI"]
dataContent2 = [230, 320, 403, 430, 312]
chartView.setLineChartData(xValues: dataContent1, yValues: dataContent2, label: "BTC")

@AlexSmet
Copy link

AlexSmet commented Jun 7, 2018

@benzai
You need to set a label count for xAxis. If you use code like in mine extension, then just add one string in your setLineChartData function:
self.xAxis.setLabelCount(xValues.count, force: true)

@stephent
Copy link

stephent commented Jun 12, 2018

@benzai I found I had to tweak @AlexSmet's approach slightly and set force: false to get my chart to display 12 months correctly:

barChartView.xAxis.setLabelCount(dataPoints.count, force: false)

When force was set to true, the chart would request oddball xAxis values in the formatter delegate (e.g. -0.5 instead of 0.0) and the labels were not aligned correctly with the corresponding yValue.

@JCMcLovin
Copy link
Contributor

The documentation markup says 'if true, the set number of y-labels will be forced' implying that this is specifically for the y-labels but it sounds like it applies to both x and y-axis labels, correct?

@reza-khalafi
Copy link

Can I set String label in left axis?

@agueroveraalvaro
Copy link

To LineChart :

self.lineChart.xAxis.valueFormatter = IndexAxisValueFormatter(values: self.chartLabels)
self.lineChart.xAxis.avoidFirstLastClippingEnabled = true

@beachstrider
Copy link

How are you today.
Please help me, I would like set the value with bar charts of Swift 4 project.

@Meri994
Copy link

Meri994 commented Oct 16, 2020

tE1U5

I want to draw this type of line chart. Between two time intervals, how to add multiple dots? (Example, wants to display multiple dots between 7 am and 8 am)

@likil33
Copy link

likil33 commented Apr 5, 2024

HI @danielgindi : Any New updates on this labels display. short code

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests