You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In issue 'Strings for Labels in Swift 3 #1732' (closed as of about 3 hours ago) the idea was to compare "my scores" for each of the last four weeks with "group scores" for the same period in a bar chart. The writer especially wanted to see how to put labels on the x-axis ("week -3", "week -2", "last week" and "this week"). Good news: below is a solution that shows the graph with the desired labels. Bad news: I have not been able to get the labels to center and, when centerAxisLabelsEnabled is set to true, the axis formatter starts receiving an index value of -1.
Details:
I'm using Xcode 8, Swift 3, and used cocoaPods to bring in the most recent version of iOS Charts. The code below is all kept in the ViewController file of a single-view app. The only object in that single view is an instance of BarChartView.
Axis Formatter Class
class WeekAxisValueFormatter: NSObject, IAxisValueFormatter {
static let weeks = [ "-3", "-2", "Last", "This" ] // xAxis labels
static let labelCount = weeks.count // count of xAxis labels
static var indexCount = 0 // for debug reporting, below
func stringForValue(_ value: Double,
axis: AxisBase?) -> String {
let index = Int( value )
// FIXME: an invalid index is sometimes encountered, report all indices here.
// Remove the defensive stuff once the bug is identified.
WeekAxisValueFormatter.indexCount += 1
print( "\( WeekAxisValueFormatter.indexCount ). Value of index: \( index )")
if index < 0 || index >= WeekAxisValueFormatter.weeks.count { return "" }
return WeekAxisValueFormatter.weeks[ index ]
}
}
ViewController class
class ViewController: UIViewController {
@IBOutlet weak var scoresBarChart: BarChartView!
private struct Lets {
// data for chart
static let myScores = [85, 86, 87, 89]
static let groupScores = [90, 95, 90, 95]
// chart text
static let myScoreLabel = "My Score"
static let groupScoreLabel = "Group Score"
static let description = "week by week score comparison"
}
override func viewDidLoad() {
super.viewDidLoad()
// Chart Properties (per BarChartViewController.m in ChartsDemo)
let cht = self.scoresBarChart!
cht.drawBarShadowEnabled = false // display gray bars indicating max values
cht.drawValueAboveBarEnabled = true // display value above bar-top not below bar-top
cht.maxVisibleCount = 6 // max no. of visible drawn values ??
// Chart Properties (beyond what is used in ChartsDemo, for legibility)
cht.backgroundColor = UIColor.lightGray // highlights the view containing the graph
cht.chartDescription?.text = Lets.description // appears as graph comment
cht.chartDescription?.textColor = UIColor.blue // color of graph comment
// X-Axis Properties (per BarChartViewController.m in ChartsDemo)
let xAxis = scoresBarChart!.xAxis
xAxis.labelPosition = XAxis.LabelPosition.bottom // place labels below X-axis
xAxis.labelFont = UIFont.systemFont( ofSize: 10 ) // label formatting
xAxis.drawGridLinesEnabled = false // do not show vertical grid lines
xAxis.granularity = 1.0 // min. interval between axis values ??
xAxis.labelCount = WeekAxisValueFormatter.labelCount // number of X-values must be in 2...25
xAxis.valueFormatter =
WeekAxisValueFormatter() // puts strings onto X-axis
// X-Axis Properties (beyond what is used in ChartsDemo, to center)
xAxis.centerAxisLabelsEnabled = true // added to overcome label misplacement
// xAxis.granularityEnabled = true // might activate granularity ??
// xAxis.axisMaximum = 1.0 // added per sree127 in issue 1556
// xAxis.axisMinimum = 1.0 // added per sree127 in issue 1556
// BarChartData setup ( per BarChartViewController.m in ChartsDemo )
let yVals1 = Lets.myScores.enumerated().map {
( index, score ) in
return BarChartDataEntry(x: Double( index) , y: Double( score ))
}
let set1 = BarChartDataSet( values: yVals1, label: Lets.myScoreLabel )
set1.colors = [ UIColor.orange ]
let yVals2 = Lets.groupScores.enumerated().map {
( index, score ) in
return BarChartDataEntry( x: Double( index ), y: Double( score ))
}
let set2 = BarChartDataSet( values: yVals2, label: Lets.groupScoreLabel )
set2.colors = [ UIColor.green ]
set2.drawValuesEnabled = false
let dataSets = [ set1, set2 ]
let data = BarChartData( dataSets: dataSets )
data.barWidth = 0.3 // width in values (not pixels)
data.groupBars( fromX: 0.015, // spacing begins
groupSpace: 0.15, // spacing between groups of bars
barSpace: 0.05 ) // spacing between individual bars
scoresBarChart.data = data
// debugging (uses BarChartData extension, not shown)
print( "\n\( data ) \n" )
}
}
Every time the X-axis-formatter is invoked it prints the index parameter to the log. Also, immediately after the scoresBarChart.data is set, the properties of the BarChartData instance is also logged. The log looks like this:
1. Value of index: 0
2. Value of index: 1
3. Value of index: 2
4. Value of index: 3
5. Value of index: 0
6. Value of index: 1
7. Value of index: 2
8. Value of index: 3
*** CHART DATA:
barWidth:.....0.3
yMax:.........95.0
yMin:.........85.0
xMax:.........3.0
xMin:.........0.0
dataSetCount: 2
*** SET: My Score
yMin:...............85.0
yMax:...............89.0
xMin:...............0.0
xMax:...............3.0
isHighlightEnabled: true
needsFormatter:.....false
isDrawEnabled:......true
visible:............true
entryCount:.........4
*** SET: Group Score
yMin:...............90.0
yMax:...............95.0
xMin:...............0.0
xMax:...............3.0
isHighlightEnabled: true
needsFormatter:.....false
isDrawEnabled:......false
visible:............true
entryCount:.........4
*** All Entries in All ChartDataSets
Labels My Score Group Score
-3 85.0 90.0
-2 86.0 95.0
Last 87.0 90.0
This 89.0 95.0
9. Value of index: -1
10. Value of index: 0
11. Value of index: 1
12. Value of index: 2
13. Value of index: 3
14. Value of index: 4
15. Value of index: -1
16. Value of index: 0
17. Value of index: 1
18. Value of index: 2
19. Value of index: 3
I'm guessing that the underlying logic is making two attempts to format the chart before it gets the data (once for each axis?) and then tries again after getting the data. The issue with an index of -1 in the X-axis label formatter goes away when the xAxis.centerAxisLabelsEnabled = true line is commented out.
What am I overlooking?
Thanks again,
Bill
The text was updated successfully, but these errors were encountered:
Well it depends on the axis ranges. If you have padding for example, or custom axisMin/axisMax, or maybe other variations, then it would make other x-values possible.
You have to keep in mind that the x-value to format is not an index, but a value. You should be able to format decimal values to labels (granularity should constrain fractions), and you should also be able to format -1 or 9999. Even if you do not have that in your array of pre-defined labels.
Because you don't have the value in your array, you may decide that the String for -1 should be ""...
Howdy, and thank you for the code!
In issue 'Strings for Labels in Swift 3 #1732' (closed as of about 3 hours ago) the idea was to compare "my scores" for each of the last four weeks with "group scores" for the same period in a bar chart. The writer especially wanted to see how to put labels on the x-axis ("week -3", "week -2", "last week" and "this week"). Good news: below is a solution that shows the graph with the desired labels. Bad news: I have not been able to get the labels to center and, when
centerAxisLabelsEnabled
is set to true, the axis formatter starts receiving an index value of -1.Details:
I'm using Xcode 8, Swift 3, and used cocoaPods to bring in the most recent version of iOS Charts. The code below is all kept in the ViewController file of a single-view app. The only object in that single view is an instance of
BarChartView
.Axis Formatter Class
ViewController class
Every time the X-axis-formatter is invoked it prints the index parameter to the log. Also, immediately after the
scoresBarChart.data
is set, the properties of theBarChartData
instance is also logged. The log looks like this:I'm guessing that the underlying logic is making two attempts to format the chart before it gets the data (once for each axis?) and then tries again after getting the data. The issue with an index of -1 in the X-axis label formatter goes away when the
xAxis.centerAxisLabelsEnabled = true
line is commented out.What am I overlooking?
Thanks again,
Bill
The text was updated successfully, but these errors were encountered: