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!!
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.
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
have you checked the ChartsDemo? I believe there are answers.
I am also looking for an answer to this, opened a case earlier here - https://github.com/danielgindi/Charts/issues/1331
Couldnt find an answer in the demos, please let me know if you find a solution. thanks
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.
@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.
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.
Any update ?
@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.
What if we want to have months displayed on the X axis ? not possible too ?
Thx.
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
I also need an easy way to customize the x-axis.. I went back to the previous version of charts because of this.
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
Sorry I was talking about "How to Modify X Axis values Swift?" using Strings
Yes me too. I used same answer of @ajimenezjulio
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.
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")
}
Hey, can have other charts extension too?
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.
Is there a solution for ObjC to format the X Axis with custom labels ?
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]
}
}
Hi,
I tried to add the solution. But i am always getting an error 'index out of range'
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 ""
}
}
Open button
@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...
@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")
@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)
@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.
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?
Can I set String label in left axis?
To LineChart :
self.lineChart.xAxis.valueFormatter = IndexAxisValueFormatter(values: self.chartLabels)
self.lineChart.xAxis.avoidFirstLastClippingEnabled = true
How are you today.
Please help me, I would like set the value with bar charts of Swift 4 project.
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)
Most helpful comment
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.
Usage