Repeating values on x-axis for iOS Charts
it because when you set your chart setup (granurality = 1 and ChartXAxisFormatter) is showing each second in xAxis
I prefer to use array date to show day in axis, with something like this
public class DateValueFormatter: NSObject, IAxisValueFormatter {
private let dateFormatter = DateFormatter()
private let dates:[Date]
init(dates: [Date]) {
self.dates= dates
super.init()
dateFormatter.dateFormat = "dd MMM HH:mm"
}
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
if value >= 0 && value < objects.count{
let date = dates[Int(value)]
return dateFormatter.string(from: date)
}
return ""
}
}
if you don't want to change your value formatted you can try to set granularity to 86400 (total seconds in 1 day)
iOS-Charts Library: x-axis labels without backing data not showing
Ok so thanks to @wingzero 's comment, I have been able to get this working. There are a few things required to do so. For simplicity's sake, I am going to explain how to get the "days of the week" labels working as I originally asked. If you follow these steps, however, you should be able to tweak them to format your chart however you like (for example, with months of the year).
1) Make sure that your chart's x-axis minimum and maximum values are set. In this case, you'd want to say: chartView.xAxis.axisMinimum = 0.0
and chartView.axisMaximum = 6.0
. This is important for step 2.
2) As Wingzero alluded to, create a subclass of XAxisRenderer
that allows us to grab the minimum and maximum values set in step one and determine what values should be passed to our IAxisValueFormatter
subclass in step three. In this case:
class XAxisWeekRenderer: XAxisRenderer {
override func computeAxis(min: Double, max: Double, inverted: Bool) {
axis?.entries = [0, 1, 2, 3, 4, 5, 6]
}
}
Make sure to pass this renderer to your chart like this: chartView.xAxisRenderer = XAxisWeekRenderer()
3) Create a subclass of IAxisValueFormatter
that takes the values we passed to the chart in step two ([0, 1, 2, 3, 4, 5, 6]) and gets corresponding label names. This is what I did in my original question here. To recap:
public class CustomChartFormatter: NSObject, IAxisValueFormatter {
var days: = ["S", "M", "T", "W", "T", "F", "S"]
public func stringForValue(value: Double, axis: AxisBase?) -> String {
return days[Int(value)]
}
}
4) Set the labelCount
on your graph to be equal to the number of labels you want. In this case, it would be 7. I show how to do this, along with the rest of the steps, below the last step here.
5) Force the labels to be enabled
6) Force granularity on the chart to be enabled and set granularity to 1. From what I understand, setting the granularity to 1 means that if the data your chart passes to stringForValue
is not in round numbers, the chart will essentially round said data or treat it like it is rounded. This is important since if you passed in 0.5, it's possible that your stringForValue
might not produce the right strings for your labels.
7) Set the value formatter on the xAxis to be the custom formatter you created in step 3.
Steps 4-7 (plus setting the formatter created in step 3) are shown below:
chartView.xAxis.labelCount = 7
chartView.xAxis.forceLabelsEnabled = true
chartView.xAxis.granularityEnabled = true
chartView.xAxis.granularity = 1
chartView.xAxis.valueFormatter = CustomChartFormatter()
How to use String values for X-Axis in Charts instead of doubles?
There's a protocol IAxisValueFormatter that you can implement and achieve your expected result.
EDIT:
How to use it
While initialising chartView.xAxis.valueFormatter = self
and implementing protocol.
extension LineChart1ViewController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
let months = ["January","February","March","April","May","June","July","Auguest","September","October","November","December"]
return months[Int(value)]
}
}
Custom xAxis formatting in iOS Charts library
You need to update your existing code as below.
- Update your data binding for XAxis:
let chartFormatter = LineChartFormatter(labels: xValues)
let xAxis = XAxis()
xAxis.valueFormatter = chartFormatter
self.xAxis.valueFormatter = xAxis.valueFormatter
Update Value Formatter code:
private class LineChartFormatter: NSObject, IAxisValueFormatter {
var labels: [String] = []
let dateFormatter = DateFormatter()
let dateShortFormatter = DateFormatter()
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
if let date = dateFormatter.date(from:labels[Int(value)]) {
if value == 0 {
dateShortFormatter.dateFormat = "MMM dd"
return dateShortFormatter.string(from: date)
} else {
let prevDate = dateFormatter.date(from:labels[Int(value - 1)])
dateShortFormatter.dateFormat = "MMM"
if dateShortFormatter.string(from: date) != dateShortFormatter.string(from: prevDate!) {
dateShortFormatter.dateFormat = "MMM dd"
return dateShortFormatter.string(from: date)
} else {
dateShortFormatter.dateFormat = "dd"
return dateShortFormatter.string(from: date)
}
}
} else {
return labels[Int(value)]
}
}
init(labels: [String]) {
super.init()
dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss Z"
self.labels = labels
}}
By Above code change, you will achieve your Date formatting in XAxis.
Related Topics
Icloud Drive Issue: "[Documentmanager] Failed to Associate Thumbnails for Picked Url"
How to Create Public Extensions, in a Shared Framework, for Xctest
Problems Accessing Calendar Using Ekeventstore on Osx Sierra with Swift 3
Calling Nsexception.Raise() in Swift
How to Make Swiftui Uiviewrepresentable View Hug Its Content
Why Do I Get "Static Member '...' Cannot Be Used on Instance of Type '...'" Error
Gmsplace Returns Invalid Coordinate (-180, -180), But Name and Place Id Are Correct
Captureoutput Function Isn't Called Using Setsamplebufferdelegate
How to Access Cfdictionary in Swift 3
"Use Default Container" Doesn't Show in Icloud Capabilities
Swift "Is" Operator with Type Stored in Variable
Swift Find Superview of Given Class with Generics
How to Make Player Move to Opposite Side While Is in a Path
Callback Url Not Approved Despite Being Provided Twitter API
A Codable Structure Contains a Protocol Property