How to make a grouped BarChart with ios-charts?

痴心易碎 提交于 2019-11-29 05:10:05

You got something wrong here. Right now you are creating a new DataSet for every year.

That is wrong.

What you need to do is create as many DataSets as you want bars per group where one DataSet represents one bar in each group. (e.g. DataSet 1 represents every first bar of a group, DataSet 2 every second bar of a group, ...)

As an example, imagine a chart like this with 4 groups of 3 bars per group. Each group represents one year.

||| ||| ||| |||

  • The setup shown above requires 3 DataSets (one for each group)
  • Entries in the same group have the same x-index (e.g. in the first group all have x-index 0)
  • It consists of a total of 12 entries
  • Each DataSet contains 4 entries with Entry x-indices ranging from 0 to 3

Here you can find an example of the scenario described above.

let months = ["Jan", "Feb", "Mar", "Apr", "May"]
    let unitsSold = [20.0, 4.0, 6.0, 3.0, 12.0]
    let unitsBought = [10.0, 14.0, 60.0, 13.0, 2.0]

     override func viewDidLoad() {
            super.viewDidLoad()
            // Do any additional setup after loading the view, typically from a nib.
            barChartView.delegate = self
            barChartView.noDataText = "You need to provide data for the chart."
            barChartView.chartDescription?.text = "sales vs bought "


            //legend
            let legend = barChartView.legend
            legend.enabled = true
            legend.horizontalAlignment = .right
            legend.verticalAlignment = .top
            legend.orientation = .vertical
            legend.drawInside = true
            legend.yOffset = 10.0;
            legend.xOffset = 10.0;
            legend.yEntrySpace = 0.0;


            let xaxis = barChartView.xAxis
            xaxis.valueFormatter = axisFormatDelegate
            xaxis.drawGridLinesEnabled = true
            xaxis.labelPosition = .bottom
            xaxis.centerAxisLabelsEnabled = true
            xaxis.valueFormatter = IndexAxisValueFormatter(values:self.months)
            xaxis.granularity = 1


            let leftAxisFormatter = NumberFormatter()
            leftAxisFormatter.maximumFractionDigits = 1

            let yaxis = barChartView.leftAxis
            yaxis.spaceTop = 0.35
            yaxis.axisMinimum = 0
            yaxis.drawGridLinesEnabled = false

            barChartView.rightAxis.enabled = false
           //axisFormatDelegate = self

            setChart()
        }

 func setChart() {
        barChartView.noDataText = "You need to provide data for the chart."
        var dataEntries: [BarChartDataEntry] = []
        var dataEntries1: [BarChartDataEntry] = []

        for i in 0..<self.months.count {

            let dataEntry = BarChartDataEntry(x: Double(i) , y: self.unitsSold[i])
            dataEntries.append(dataEntry)

            let dataEntry1 = BarChartDataEntry(x: Double(i) , y: self.self.unitsBought[i])
            dataEntries1.append(dataEntry1)

            //stack barchart
            //let dataEntry = BarChartDataEntry(x: Double(i), yValues:  [self.unitsSold[i],self.unitsBought[i]], label: "groupChart")



        }

        let chartDataSet = BarChartDataSet(values: dataEntries, label: "Unit sold")
        let chartDataSet1 = BarChartDataSet(values: dataEntries1, label: "Unit Bought")

        let dataSets: [BarChartDataSet] = [chartDataSet,chartDataSet1]
        chartDataSet.colors = [UIColor(red: 230/255, green: 126/255, blue: 34/255, alpha: 1)]
        //chartDataSet.colors = ChartColorTemplates.colorful()
        //let chartData = BarChartData(dataSet: chartDataSet)

        let chartData = BarChartData(dataSets: dataSets)


        let groupSpace = 0.3
        let barSpace = 0.05
        let barWidth = 0.3
        // (0.3 + 0.05) * 2 + 0.3 = 1.00 -> interval per "group" 

        let groupCount = self.months.count
        let startYear = 0


        chartData.barWidth = barWidth;
        barChartView.xAxis.axisMinimum = Double(startYear)
        let gg = chartData.groupWidth(groupSpace: groupSpace, barSpace: barSpace)
        print("Groupspace: \(gg)")
        barChartView.xAxis.axisMaximum = Double(startYear) + gg * Double(groupCount)

        chartData.groupBars(fromX: Double(startYear), groupSpace: groupSpace, barSpace: barSpace)
        //chartData.groupWidth(groupSpace: groupSpace, barSpace: barSpace)
        barChartView.notifyDataSetChanged()

        barChartView.data = chartData






        //background color
        barChartView.backgroundColor = UIColor(red: 189/255, green: 195/255, blue: 199/255, alpha: 1)

        //chart animation
        barChartView.animate(xAxisDuration: 1.5, yAxisDuration: 1.5, easingOption: .linear)


    }

if you have noticed in above code in function chart. There is let

 groupSpace = 0.3
 let barSpace = 0.05
 let barWidth = 0.3
 // (0.3 + 0.05) * 2 + 0.3 = 1.00 -> interval per "group" 

which will make equation (groupSpace * barSpace) * n + groupSpace = 1

you need to play around this equation for n number of bars

I've tried Rajan Twanabashu solution, but it was almost the good one. Maybe it has changed since, I don't know.

Here's what I've done, after I found the groupWidth function in the BarDataChart file from Charts.

groupWidth function declaration

let groupSpace = 1 - n * (barWidth + barSpace)

Hope it could help

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!