Displaying Data with iOS Charts

I am creating an ios Chart that is based off of documents in Firestore. Here is my code:

import UIKit
import Charts
import Firebase
import FirebaseFirestoreSwift
import FirebaseAuth


class YearChartViewController: UIViewController, ChartViewDelegate {


enum valetTimeCategory: String{
    typealias RawValue = String
    
    case Year = "Year"
    case Month = "Month"
    case DaysOfWeeks = "Day1"
    case CalendarDays = "Day2"
    case Hour = "Hour"
    
}

var selectedCategory = valetTimeCategory.Year.rawValue


    
    


private var yearListener: ListenerRegistration!

@IBOutlet weak var segmentedController: UISegmentedControl!

var timeRetrieval = [timeData]()

var timeRetrievalYear = [yearTimeData]()

var barChart = BarChartView()

var pieChart = PieChartView()

lazy var companyUser = ""

@IBOutlet weak var localeIdLabel: UILabel!

private var timeDataCollection: CollectionReference!

var documentName1 = ""

override func viewDidLoad() {
    super.viewDidLoad()
    barChart.delegate = self
    
    pieChart.delegate = self
    
    localeIdLabel.text = companyUser
    
    timeDataCollection = Firestore.firestore().collection("users").document(companyUser ).collection("time_data")
    
    
}


@IBAction func valetTimeCategory3(_ sender: Any) {
    switch segmentedController.selectedSegmentIndex {
    case 0:
        selectedCategory = valetTimeCategory.Year.rawValue
    case 1:
        selectedCategory = valetTimeCategory.Month.rawValue
    case 2:
        selectedCategory = valetTimeCategory.DaysOfWeeks.rawValue
    case 3: selectedCategory = valetTimeCategory.CalendarDays.rawValue
    case 4: selectedCategory = valetTimeCategory.Hour.rawValue
    default:
        valetTimeCategory.Year.rawValue
    }
    self.yearListener.remove()
    setListener()
}




override func viewDidLayoutSubviews() {
    super.viewDidLayoutSubviews()
    
    setListener()
        
    
                                                }

func setListener() {
    barChart.frame = CGRect(x: 0, y: 0, width: 250, height: 250)
    barChart.center = view.center
    
    view.addSubview(barChart)
        
   var entries = [BarChartDataEntry]()
   
        
    
    yearListener = timeDataCollection.whereField(selectedCategory, isNotEqualTo: "Yaguay").order(by: selectedCategory).addSnapshotListener{ (querySnapshot, error) in
        if let err = error {
            debugPrint("Error fetching docs: \(err)")
        } else {
            self.timeRetrieval.removeAll()
         guard let snap = querySnapshot else { return }
         for document in snap.documents {

            let FirebaseData = document.data()
            let tiempoEs1 = FirebaseData["Year"] as? String ?? ""
            let tiempoEs2 = FirebaseData["Month"] as? String ?? ""
            let tiempoEs3 = FirebaseData["Day1"] as? String ?? ""
            let tiempoEs4 = FirebaseData["Hour"] as? String ?? ""
            let tiempoEs5 = FirebaseData["Day2"] as? String ?? ""
            let documentIdThird = document.documentID
            
            let newTimeRetrieval = timeData(timeContinuum1: tiempoEs1, timeContinuum2: tiempoEs2, timeContinuum3: tiempoEs3, timeContinuum4: tiempoEs4, timeContinuum5: tiempoEs5, documentId3: documentIdThird);
            
            let newYearRetrieval = yearTimeData(timeContinuumYear: tiempoEs1)
            self.timeRetrieval.append(newTimeRetrieval)
            self.timeRetrievalYear.append(newYearRetrieval);
            
            if self.selectedCategory == valetTimeCategory.Year.rawValue {
                let q = Int(tiempoEs1)
                
                let b = q?.nonzeroBitCount
                
                entries.append(BarChartDataEntry(x: Double(q!), y: Double(self.timeRetrieval.count)));
                
                
                let set = BarChartDataSet(entries: entries
                )
                
                set.colors = ChartColorTemplates.joyful()
                
                let data = BarChartData(dataSet: set)
                
                self.barChart.data = data
                
                let format = NumberFormatter()
                format.numberStyle = .decimal
                  let formatter = DefaultValueFormatter(formatter: format)
                
                data.setValueFormatter(formatter)
                
                self.barChart.legendRenderer.computeLegend(data: BarChartData(dataSet: set))
                
                self.barChart.chartDescription?.text = "Years"
                
                self.yearListener.remove()
            }
            
            if self.selectedCategory == valetTimeCategory.Month.rawValue {
                let d = tiempoEs2.hashValue.nonzeroBitCount
                
                
                entries.append(BarChartDataEntry(x: Double(d), y: Double(self.timeRetrieval.count)));
                
                let set = BarChartDataSet(entries: entries, label: "\(self.selectedCategory)"
                )
                
                print(self.selectedCategory)
                
                set.colors = ChartColorTemplates.joyful()
                
                let data = BarChartData(dataSet: set)
                
                self.barChart.data = data
                
                self.yearListener.remove()
            }
            
            if self.selectedCategory == valetTimeCategory.DaysOfWeeks.rawValue {
                let d = tiempoEs3.hashValue.nonzeroBitCount
                
                entries.append(BarChartDataEntry(x: Double(d), y: Double(self.timeRetrieval.count)));
                
                let set = BarChartDataSet(entries: entries, label: "\(self.selectedCategory)"
                )
                
                print(self.selectedCategory)
                
                set.colors = ChartColorTemplates.joyful()
                
                let data = BarChartData(dataSet: set)
                
                self.barChart.data = data
                
                self.yearListener.remove()
            }
            
            if self.selectedCategory == valetTimeCategory.CalendarDays.rawValue {
                let q = Int(tiempoEs5)
                
                let b = q?.nonzeroBitCount
                
                entries.append(BarChartDataEntry(x: Double(b!), y: Double(self.timeRetrieval.count)));
                
                let set = BarChartDataSet(entries: entries, label: "\(self.selectedCategory)"
                )
                
                print(self.selectedCategory)
                
                set.colors = ChartColorTemplates.joyful()
                
                let data = BarChartData(dataSet: set)
                
                self.barChart.data = data
                
                self.yearListener.remove()
            }
            
            if self.selectedCategory == valetTimeCategory.Hour.rawValue {
                let q = tiempoEs4.hashValue.nonzeroBitCount
                
                entries.append(BarChartDataEntry(x: Double(q), y: Double(self.timeRetrieval.count)));
                
                let set = BarChartDataSet(entries: entries, label: "\(self.selectedCategory)"
                )
                
                print(self.selectedCategory)
                
                set.colors = ChartColorTemplates.joyful()
                
                let data = BarChartData(dataSet: set)
                
                self.barChart.data = data
                
                self.yearListener.remove()
            }
            
           
            
    

                        }
                        
                        

                        
         }
             }
    
}




@IBAction func monthButton1Tapped(_ sender: Any) {
    self.companyUser = localeIdLabel.text!
    performSegue(withIdentifier: "Month", sender: self)
}


@IBAction func logout(_ sender: Any) {
    let auth = Auth.auth()
    do {
        try auth.signOut()
        transitionToHome()
    } catch let signOutError as Error {
        debugPrint(signOutError)
    }
}

func transitionToHome() {
    let homeViewController = storyboard?.instantiateViewController(identifier: Constants.Storyboard.homeViewController)
    
    view.window?.rootViewController = homeViewController
    view.window?.makeKeyAndVisible()
}



override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
         let vc = segue.destination as! MonthChartViewController
    vc.documentName = self.companyUser

   }

                                                    }

Hopefully the random, nonsensical names aren’t too distracting, but my problem is my Bar Chart isn’t exactly displaying the right data. When I run the code, it displays:

Chart Image

There are 22 items (documents) in my collection. So it explicitly displays 22 objects, and if you count the numbers on each bar, the count on each bar is the correct number in each category (5 for 2020 and 17 for 2021). I don’t know how to get my bar chart to explicitly display “17” and “5” for each category, please help if you know how to solve this.

To be clear, the count in the array I am using (timeRetrieval) ends up being 22. I thought that Charts would divide up that count among the two bars (one for each category: 2020 and 2021, although I haven’t figured out how to put labels for these separate bars yet), but it instead it explicitly shows “22” on the screen. The picture shows “1 2 3 4 5” on the first bar, and the second bar says “6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22”. The count (of the numbers displayed on each bar) on each bar shows the correct amount of documents pertaining to each category (5 for 2020, 17 for 2021), but how can I get charts to show these numbers vs. the numbers it is currently displaying?

Inside your loop, you can have a “display count” that increments everytime starting from 0

once it will move to the next year, the last number is the one you should display in your chart

1 Like

No kidding?! Could you comment an example syntax? This is so helpful!