Search code examples
swift3ios-charts

IOS Charts - Stack Bar Chart won't stack


For some reason my two data sets overlay one an other, rather stack as shown below. Monday for example should total 22. Wednesday should total 6.

enter image description here

I create two datasets because I wish to change the color of each:

let chartDataSet1 = BarChartDataSet(values: dataEntries1, label: "Points")
chartDataSet1.barBorderColor = .gray
let chartDataSet2 = BarChartDataSet(values: dataEntries2, label: "Scans")
chartDataSet2.barBorderColor = .red

...

class ViewController: UIViewController {

    @IBOutlet weak var barChartView: BarChartView!

    override func viewDidLoad() {
        super.viewDidLoad()

        barChartView.descriptionText = ""
        barChartView.xAxis.labelPosition = .bottom
        let ll = ChartLimitLine(limit: 10.0, label: "Target")
        barChartView.rightAxis.addLimitLine(ll)
        setChart()
    }

    func setChart(){
        let months = ["Mon", "Tues", "Wed", "Thu", "Fri", "Sat", "Sun"]
        let points = [20.0, 4.0, 3.0, 6.0, 12.0, 16.0, 4.0]
        let scans = [2.0, 4.0, 3.0, 6.0, 2.0, 4.0, 2.0]
        barChartView.setBarChartData(xValues: months, yValues1: scans, yValues2: points)

    }
}

......

extension BarChartView {


    func setBarChartData(xValues: [String], yValues1: [Double], yValues2 : [Double]) {

        var dataEntries1: [BarChartDataEntry] = []
        var dataEntries2: [BarChartDataEntry] = []

        for i in 0..<yValues1.count {
            let dataEntry1 = BarChartDataEntry(x: Double(i), yValues:  [yValues1[i]], label: "Points")
            // let dataEntry = BarChartDataEntry(x: Double(i), y: yValues[i])
            dataEntries1.append(dataEntry1)
        }

        for i in 0..<yValues2.count {
            let dataEntry2 = BarChartDataEntry(x: Double(i), yValues:  [yValues2[i]], label: "Scans")
            // let dataEntry = BarChartDataEntry(x: Double(i), y: yValues[i])
            dataEntries2.append(dataEntry2)
        }
        let chartDataSet1 = BarChartDataSet(values: dataEntries1, label: "Points")
        chartDataSet1.barBorderColor = .gray
        let chartDataSet2 = BarChartDataSet(values: dataEntries2, label: "Scans")
        chartDataSet2.barBorderColor = .red
        let chartData = BarChartData(dataSets: [chartDataSet1, chartDataSet2])

        let chartFormatter = BarChartFormatter(labels: xValues)
        let xAxis = XAxis()
        xAxis.valueFormatter = chartFormatter
        self.xAxis.valueFormatter = xAxis.valueFormatter

        self.data = chartData
    }
}

If I combine my chartDataSet1 and chartDataSet2 into one array, the bars stack properly, but then I can't figure out how to change the color of each:


Solution

  • You have to set bar chart data like this :

    extension BarChartView {
    
        func setBarChartData(xValues: [String], yValues1: [Double], yValues2 : [Double]) {
    
            var dataEntries1: [BarChartDataEntry] = []
            for i in 0..<yValues1.count {
                let dataEntry1 = BarChartDataEntry(x: Double(i), yValues:  [yValues1[i], yValues2[i]], label: "Points")
                dataEntries1.append(dataEntry1)
            }
    
            let chartDataSet1 = BarChartDataSet(values: dataEntries1, label: "Points")
            chartDataSet1.barBorderColor = .red
            chartDataSet1.stackLabels = ["Points", "Scans"]
            chartDataSet1.colors =  [UIColor.darkGray, UIColor.lightGray]
    
            let chartData = BarChartData(dataSets: [chartDataSet1])
    
            let chartFormatter = BarChartFormatter(labels: xValues)
            let xAxis = XAxis()
            xAxis.valueFormatter = chartFormatter
            self.xAxis.valueFormatter = xAxis.valueFormatter
            self.data = chartData
        }
    }