Objective
I'm trying to display data from two sets (ACTIVE and REST) in a bar chart. The sets are alternating (meaning there is one ACTIVE interval, followed by a REST interval, etc...). Rather, there is alwats one REST set between every two ACTIVE sets.
The code I've used is below, for reference. I am, however, running into problems with the bar positions and spacing.
Issue: centering bar at x-value
First issue, the bar is not centered at the corresponding x-value. In the example below, the first orange bar has x = 1.
It clearly starts at value 1 on the x axis (its leftmost side corresponds to about 1), but I want it to be centered around the 1 value on the x-axis
Issue: bar spacing
For some reason, the bars intersection and the spacing is not equal (see screenshot). Note the white space between bar 2 and 3, and the absence of space between bar 1 and 2.
The relevant code here is :
let barWidth = 1.0
let barSpace = 0.10
let groupSpace = 0.1
chartData.groupBars(fromX: 1, groupSpace: groupSpace, barSpace: barSpace)
chartData.barWidth = barWidth
Indexing bars and BarChartDataEntry
Each set (REST and ACTIVE) comes from a different array of values.
If I press on the 1st REST bar, I would like to obtain the corresponding value of 0. on the 1st ACTIVE bar, the value 0 also. 2nd ACTIVE bar, value 1...
However, in chartValueSelected
, using the entry.x
value gives the bar's x-position on the axis (NOT the x value I've set in the code), which is casing errors.
How can I get the value of the selected bar's index in the set it belongs to ?
Code
//
// MARK: Chart Setup
//
func setupBarChart() {
let intervals = self.session!.getIntervals()
// Set chart delegate
intervalBarChartView.delegate = self
//
// Create pairs (x, y) of values
//
var values_ACTIVE : [BarChartDataEntry] = []
var values_REST : [BarChartDataEntry] = []
for i in 0...(intervals.count - 1) {
let newValue_ACTIVE = intervals[i].duration!.doubleValue
// let newIndex_ACTIVE = Double(2*i+1)
let newIndex_ACTIVE = Double(i)
values_ACTIVE += [BarChartDataEntry(x: newIndex_ACTIVE, y: newValue_ACTIVE)]
if i < (intervals.count - 1) {
let newValue_REST = (intervals[i+1].startTime!.doubleValue) - intervals[i].getEndTime()!
// let newIndex_REST = Double(2*i+2)
let newIndex_REST = Double(i)
values_REST += [BarChartDataEntry(x: newIndex_REST, y: newValue_REST)]
}
}
// Create data sets
let dataSet_ACTIVE = BarChartDataSet(values: values_ACTIVE, label: "ACTIVE")
let dataSet_REST = BarChartDataSet(values: values_REST, label: "REST")
//Set chart data
let chartData = BarChartData()
chartData.addDataSet(dataSet_REST)
chartData.addDataSet(dataSet_ACTIVE)
self.intervalBarChartView.data = chartData
// Bar sizes
let barWidth = 1.0
let barSpace = 0.10
let groupSpace = 0.1
chartData.groupBars(fromX: 0, groupSpace: groupSpace, barSpace: barSpace)
chartData.barWidth = barWidth
// Bar Colors
dataSet_ACTIVE.colors = [runOrange]
dataSet_REST.colors = [RunGreen]
self.intervalBarChartView.gridBackgroundColor = NSUIColor.white
// Enable/Disable show values and position of values
chartData.setDrawValues(false)
intervalBarChartView.drawValueAboveBarEnabled = false
// Bar Axes:
intervalBarChartView.xAxis.axisMinimum = 0.0
intervalBarChartView.xAxis.axisMaximum = 10
intervalBarChartView.leftAxis.axisMinimum = 0.0
intervalBarChartView.rightAxis.enabled = false
// Bar Axes: GridLines
self.intervalBarChartView.xAxis.drawGridLinesEnabled = false
self.intervalBarChartView.xAxis.drawAxisLineEnabled = false
self.intervalBarChartView.rightAxis.drawAxisLineEnabled = true
self.intervalBarChartView.rightAxis.drawGridLinesEnabled = false
self.intervalBarChartView.leftAxis.drawGridLinesEnabled = false
self.intervalBarChartView.leftAxis.drawAxisLineEnabled = false
// Bar Text
self.intervalBarChartView.chartDescription?.text = "Barchart Demo"
// Control interaction
self.intervalBarChartView.doubleTapToZoomEnabled = false
}
EDIT
Here is what I get with two different compilations of settings :
With these settings :
// Bar sizes
let barWidth = 0.3
let barSpace = 0.10
let groupSpace = 0.1
The gap between the bars is (more or less) equal:
However, with these setttings:
let groupSpace = 0.3
let barSpace = 0.05
let barWidth = 0.3
I get a wider gap between bars 2 and 3 (compared to 1 and 2)