Is there a way with the iOs Charts lib (3.6.0) to scale the Y axis with the nearest hundred, thousands, etc ?
I'm probably missing something but my Y axis doesn't make any sense :
In this exemple, I would like my Y axis to be something like :
75 000
60 000
45 000
30 000
15 000
0
-15 000
I tried using autoScaleMinMaxEnabled
but it doesn't seem to work.
I don't understand how to make the y axis use rounded numbers ?
Thank you for your help
Update :
Here is the code I use, as requested :
class GraphCustomView : LineChartView, ChartViewDelegate {
//MARK: Variables
var graphModel: [GraphModel] = []
// Initialize Chart
public func initializeChart(graphModel: [GraphModel], devise: String, withouthFill: Bool? = true) {
self.graphModel = [GraphModel]()
self.graphModel = graphModel
self.delegate = self
self.chartDescription?.enabled = false
// xAxis
self.xAxis.enabled = true
self.xAxis.drawGridLinesEnabled = false
self.xAxis.labelPosition = .bottom
self.xAxis.valueFormatter = DateValueFormatter(miniTime: graphModel.first!.miniDate)
self.xAxis.labelFont = UIFont(name: "Ubuntu", size: 8)!
self.xAxis.labelRotationAngle = -20
self.xAxis.granularityEnabled = true
self.xAxis.granularity = 1
// RightAxis
self.rightAxis.enabled = false
self.rightAxis.drawGridLinesEnabled = false
// LeftAxis
self.leftAxis.drawGridLinesEnabled = true
self.leftAxis.gridColor = .gray
self.leftAxis.gridLineDashLengths = [CGFloat(1.5)]
self.leftAxis.labelFont = UIFont(name: "Ubuntu", size: 8)!
// General chart settings
self.drawBordersEnabled = false
self.setScaleEnabled(true)
leftAxis.setLabelCount(7, force: true)
leftAxis.drawTopYLabelEntryEnabled = true
leftAxis.drawBottomYLabelEntryEnabled = true
// Legend
self.leftAxis.labelFont = UIFont(name: "Ubuntu", size: 11)!
self.xAxis.labelFont = UIFont(name: "Ubuntu", size: 11)!
let l = self.legend
l.form = .circle
l.horizontalAlignment = .right
l.verticalAlignment = .bottom
l.orientation = .horizontal
l.drawInside = false
l.font = UIFont(name: "Ubuntu", size: 8)!
// Overdrawn line
let minValue = graphModel.first!.minValue
let maxValue = graphModel.first!.maxValue
var range: Double = 0.0
if (maxValue - minValue != 0) {
range = (maxValue - minValue) / 7
}
if (graphModel.first!.minValue - (range * 2) < graphModel.first!.overdrawn && graphModel.first!.overdrawn < graphModel.first!.minValue) {
self.leftAxis.axisMinimum = graphModel.first!.overdrawn
}
let limit: ChartLimitLine = ChartLimitLine()
limit.label = "Overdrawn"
limit.limit = graphModel.first!.overdrawn
limit.valueTextColor = .red
limit.lineColor = .red
limit.lineDashLengths = [10, 5]
leftAxis.addLimitLine(limit)
// Marker/Tooltip
let marker = XYMarkerView(color: .darkGray,
font: UIFont(name: "Ubuntu", size: 12)!,
textColor: .white,
insets: UIEdgeInsets(top: 8, left: 8, bottom: 20, right: 8),
xAxisValueFormatter: DateValueFormatter(miniTime: graphModel.first!.miniDate),
yAxisValueFormatter: MarkerValueFormatter(devise: devise))
marker.chartView = self
marker.minimumSize = CGSize(width: 80, height: 40)
self.marker = marker
self.isMultipleTouchEnabled = true
self.highlightPerTapEnabled = true
self.highlightPerDragEnabled = true
// Add data to chart
self.updateChartData()
}
public func updateChartData() {
// Creating dataSets
var dataSets: [LineChartDataSet] = [LineChartDataSet]()
// We need to sort the data in order to add it to the graph
for graph in self.graphModel {
graph.chartData.sort(by: { $0.x < $1.x })
let dataSet : LineChartDataSet = LineChartDataSet(entries: graph.chartData, label: graph.name)
dataSet.circleRadius = 0
dataSet.colors = graph.color
dataSet.drawValuesEnabled = false
dataSet.lineWidth = 2
dataSet.mode = .cubicBezier
let leftAxis = self.leftAxis
leftAxis.drawLimitLinesBehindDataEnabled = true
dataSet.fillColor = graph.color.first!
dataSet.drawFilledEnabled = true
// Add to datasets
dataSets.append(dataSet)
}
// Styling data
let data = LineChartData(dataSets: dataSets)
data.setValueFont(UIFont(name: "Ubuntu", size: 7)!)
// Displaying graph
self.data = data
}
Here is the data I used for this specific chart :
[{\"pointDate\":\"2016-11-01T00:00:00\",\"pointValue\":45375.800000000003},{\"pointDate\":\"2016-11-01T00:00:00\",\"pointValue\":45375.800000000003},{\"pointDate\":\"2016-10-31T00:00:00\",\"pointValue\":54755.580000000002},{\"pointDate\":\"2016-10-30T00:00:00\",\"pointValue\":34324.199999999997},{\"pointDate\":\"2016-10-29T00:00:00\",\"pointValue\":43846.059999999998},{\"pointDate\":\"2016-10-28T00:00:00\",\"pointValue\":29243.779999999999},{\"pointDate\":\"2016-10-27T00:00:00\",\"pointValue\":28238.439999999999},{\"pointDate\":\"2016-10-26T00:00:00\",\"pointValue\":-11461.74},{\"pointDate\":\"2016-10-25T00:00:00\",\"pointValue\":-5756.5500000000002},{\"pointDate\":\"2016-10-24T00:00:00\",\"pointValue\":27565.939999999999},{\"pointDate\":\"2016-10-23T00:00:00\",\"pointValue\":40770.910000000003},{\"pointDate\":\"2016-10-22T00:00:00\",\"pointValue\":46875.870000000003},{\"pointDate\":\"2016-10-21T00:00:00\",\"pointValue\":44609.540000000001},{\"pointDate\":\"2016-10-20T00:00:00\",\"pointValue\":43970.769999999997},{\"pointDate\":\"2016-10-19T00:00:00\",\"pointValue\":43262.910000000003},{\"pointDate\":\"2016-10-18T00:00:00\",\"pointValue\":22016.080000000002},{\"pointDate\":\"2016-10-17T00:00:00\",\"pointValue\":45001.940000000002},{\"pointDate\":\"2016-10-16T00:00:00\",\"pointValue\":44443.739999999998},{\"pointDate\":\"2016-10-15T00:00:00\",\"pointValue\":61521.720000000001},{\"pointDate\":\"2016-10-14T00:00:00\",\"pointValue\":31674.16},{\"pointDate\":\"2016-10-13T00:00:00\",\"pointValue\":42767.040000000001},{\"pointDate\":\"2016-10-12T00:00:00\",\"pointValue\":55202.110000000001},{\"pointDate\":\"2016-10-11T00:00:00\",\"pointValue\":76274.100000000006},{\"pointDate\":\"2016-10-10T00:00:00\",\"pointValue\":39097.07},{\"pointDate\":\"2016-10-09T00:00:00\",\"pointValue\":13742.99},{\"pointDate\":\"2016-10-08T00:00:00\",\"pointValue\":9616.2199999999993},{\"pointDate\":\"2016-10-07T00:00:00\",\"pointValue\":1450.6099999999999},{\"pointDate\":\"2016-10-06T00:00:00\",\"pointValue\":5820.5},{\"pointDate\":\"2016-10-05T00:00:00\",\"pointValue\":-9522.75},{\"pointDate\":\"2016-10-04T00:00:00\",\"pointValue\":8317},{\"pointDate\":\"2016-10-03T00:00:00\",\"pointValue\":7923.6499999999996},{\"pointDate\":\"2016-10-02T00:00:00\",\"pointValue\":10249.889999999999},{\"pointDate\":\"2016-10-01T00:00:00\",\"pointValue\":2388.6799999999998},{\"pointDate\":\"2016-09-30T00:00:00\",\"pointValue\":0}]
And the code use to format it a bit :
for point in pointevo.pointEvolution {
let date = point.pointDate.toDate()
let timeInSecondes = date?.timeIntervalSince1970
if (firstTime) {
self.miniDate = timeInSecondes!
firstTime = false
minValue = point.pointValue
maxValue = point.pointValue
}
if (point.pointValue < minValue) {
minValue = point.pointValue
}
if (point.pointValue > maxValue) {
maxValue = point.pointValue
}
chartData.append(ChartDataEntry(x: (timeInSecondes! - miniDate) / (3600.0 * 24.0), y: point.pointValue))
if tempPointValue.firstIndex(of: point.pointValue) == nil {
tempPointValue.append(point.pointValue)
}
}
EDITED AFTER DISCUSSIONS
As I test your code with your data I found the root of your issue. In your code it's the line:
leftAxis.setLabelCount(7, force: true)
If force parameter is set to true - it override the default calculated labels and force the labels to be exact number of labels you specified and it will spread by equal distance.
If not force it - when there will be not exact number of labels specified, I got 6 lines (and labels). So it's now up to you how to better use it.
Here also examples of results if force parameter is true and false (I set here xaxis and overdraw values to some static values).
Below the first one answer for some other situation.
You can use for it IAxisValueFormatter protocol method stringForValue(_ value:, axis:). You can round your value here and place additional symbols, like currencies symbol, like I do. Something like this:
extension ChartController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
if axis is XAxis {
// do something you need for X axis
return valueTransformedToString
} else {
// do something you need for Y axis
return valueTransformedToString
}
}
}