Reputation: 65
I am using iOS charts (V3.3) to draw a horizontal bar chart for player performance statistics for a sports app. I want the bar value to be shown next to the bar in each case. I can make this happen provided that the player has both negative and positive performance points, but if the player only has positive performance points, no values are shown.
I have the BarChartView in its own class, and am using this code
import Charts
class PlayerPerformanceBarChart: HorizontalBarChartView, IValueFormatter {
override init(frame: CGRect) {
super.init(frame: frame)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setChart(pf: [PerformanceStat]) {
noDataTextColor = Style.labelText
noDataText = gf.getLiteral("noPerformanceData")
isUserInteractionEnabled = false
legend.enabled = false
leftAxis.enabled = false
rightAxis.enabled = false
chartDescription?.text = nil
drawValueAboveBarEnabled = true
// Data
var dataEntries: [BarChartDataEntry] = []
var labels: [String] = []
for i in 0..<pf.count {
dataEntries.append(BarChartDataEntry(x: Double(i), y: Double(pf[i].playerPoints)))
labels.append(pf[i].playerAction)
}
let chartDataSet = BarChartDataSet(entries: dataEntries, label: nil)
chartDataSet.colors = ChartColorTemplates.joyful()
chartDataSet.valueFormatter = self
let chartData = BarChartData(dataSets: [chartDataSet])
chartData.setDrawValues(true)
// X Axis - which for a Horizontal Bar Chart is actually the vertical (Y) axis - I know, crazy but true!!
let xaxis = self.xAxis
xaxis.drawGridLinesEnabled = false
xaxis.labelPosition = .bottom
xaxis.labelCount = pf.count
xaxis.axisMinimum = -1
xaxis.resetCustomAxisMin()
xaxis.centerAxisLabelsEnabled = false
xaxis.granularity = 1
xaxis.granularityEnabled = true
xaxis.labelTextColor = Style.chartText
xaxis.valueFormatter = IndexAxisValueFormatter(values: labels)
clipValuesToContentEnabled = true
//Chart Format and Display
data = chartData
}
func stringForValue(_ value: Double, entry: ChartDataEntry, dataSetIndex: Int, viewPortHandler: ViewPortHandler?) -> String {
return Int(value).description
}
}
The function setChart is called by the containing view (which is a UIScrollView)
It is only a single data set, so no grouping. I cannot find out why the values would not show when there are no negative values to display. Looking at the Charts code, it is something to do with the position of the bar being outside the bounds of the viewport handler, but I cannot see why that would be the case.
Any help would be appreciated
Upvotes: 0
Views: 1403
Reputation: 567
It's better to create a separate class responsible for the values formatting.
import UIKit
import Charts
class ValueFormatter: NSObject, IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
/// your code for formatting the values
}
}
And you should assign the custom class as your value formatter:
xAxis.valueFormatter = ValueFormatter()
Aside from that, please, take a look at this wonderful tutorial on how to set the custom values for the labels: https://medium.com/@spmandrus/ios-charts-custom-y-axis-values-e03cac8850c
Upvotes: 0