1

I am working on a project of step counter, Where I have to implement the functionality to store the current day steps and append it to ios bar chart data according to the day names. Basically I want to represent the total step counts on the daily weekday basis on ios Bar Chart. It will be very helpful if I get some example code or any hint to append daily steps According to the day name.

Here is my code:-

import UIKit
import Charts

enum WeekDayName: String {
    case Sunday = "Sun"
    case Monday = "Mon"
    case Tuesday = "Tue"
    case Wednesday = "Wed"
    case Thursday = "Thu"
    case Friday = "Fri"
    case Saturday = "Sat"

}

class HistoryViewController: UIViewController,ChartViewDelegate {

    @IBOutlet weak var barChartView: BarChartView!

    var todayName:String!
    let week = ["Sun", "Mon", "Tue", "Wed","Thu", "Fri", "Sat"]
//    let unitsSold = [20.0, 4.0, 6.0, 3.0, 12.0, 16.0, 4.0, 18.0, 2.0, 4.0, 5.0, 4.0]
    let staticSteps = [200, 400, 600, 300, 1200, 1600, 400]

    override func viewDidLoad() {
        super.viewDidLoad()

        getCurrentDayName()

        setup(barLineChartView: barChartView)
    }

    //MARK: Get Current Day Name
    func getCurrentDayName(){
        let weekday = Calendar.current.component(.weekday, from: Date())
        print(weekday)
        switch weekday {
        case 1:
           todayName = WeekDayName.Sunday.rawValue
        case 2:
           todayName = WeekDayName.Monday.rawValue
        case 3:
           todayName = WeekDayName.Tuesday.rawValue
        case 4:
           todayName = WeekDayName.Wednesday.rawValue
        case 5:
           todayName = WeekDayName.Thursday.rawValue
        case 6:
           todayName = WeekDayName.Friday.rawValue
        case 7:
           todayName = WeekDayName.Saturday.rawValue
        default:
            print("nothng")
        }
        print(todayName)
    }


    func setup(barLineChartView chartView: BarChartView) {
        chartView.chartDescription?.enabled = false

        chartView.isUserInteractionEnabled = false //Disables the selection for bar charts
        chartView.dragEnabled = true
        chartView.setScaleEnabled(false) //turn off scaling /kinda pinch zoom type
        chartView.pinchZoomEnabled = false //disables pinch zoom


        let xAxis = chartView.xAxis
        xAxis.labelPosition = .bottom
        xAxis.labelFont = .systemFont(ofSize: 10)

        //hides grid
        xAxis.drawGridLinesEnabled = false


        chartView.xAxis.valueFormatter = WeekValueFormatter()



        xAxis.labelCount = 7
        chartView.animate(yAxisDuration: 3)      
       chartView.rightAxis.enabled = false

        let leftAxisFormatter = NumberFormatter()
        leftAxisFormatter.minimumFractionDigits = 0
        leftAxisFormatter.maximumFractionDigits = 1

        let leftAxis = chartView.leftAxis
        leftAxis.labelFont = .systemFont(ofSize: 10)
        leftAxis.labelCount = 8
        leftAxis.valueFormatter = DefaultAxisValueFormatter(formatter: leftAxisFormatter)
        leftAxis.labelPosition = .outsideChart
        leftAxis.spaceTop = 0.15
        leftAxis.axisMinimum = 0 // FIXME: HUH?? this replaces startAtZero = YES


        let l = chartView.legend
        l.horizontalAlignment = .left
        l.verticalAlignment = .bottom
        l.orientation = .horizontal
        l.drawInside = false
        l.form = .circle
        l.formSize = 9
        l.font = UIFont(name: "HelveticaNeue-Light", size: 11)!
        l.xEntrySpace = 4

        //setChart(dataPoints: months, values: unitsSold.map { Double($0) })
        setChart(dataPoints: week, values: staticSteps)
    }

    func setChart(dataPoints: [String], values: [Int]) {
        barChartView.noDataText = "You need to provide data for the chart."

        var dataEntries: [BarChartDataEntry] = []

        for i in 0..<dataPoints.count {
            let dataEntry = BarChartDataEntry(x: Double(i), y: Double(values[i]))
            dataEntries.append(dataEntry)
        }

        let chartDataSet = BarChartDataSet(entries: dataEntries, label: "BeWell Workout Chart")
        chartDataSet.colors = ChartColorTemplates.colorful()
        let chartData = BarChartData(dataSet: chartDataSet)
        barChartView.data = chartData
    }



//MARK: Weeks Bottom Label Class for x-Axis labels
public class WeekValueFormatter: NSObject, IAxisValueFormatter {

    override init() {
        super.init()
    }

    public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
        let weekday = Calendar.current.component(.weekday, from: Date())
        let week = ["Sun", "Mon", "Tue", "Wed","Thu", "Fri", "Sat"]

        return week[Int(value)]
    }
}
Ben Smith
  • 159
  • 1
  • 1
  • 9
  • week days are perfectly aligned to the x-axis , lets say i walk how many steps everyday i want to show the total steps count according to the week day , how can i achieve that – Ben Smith Nov 01 '19 at 05:24
  • @bhealth, Yes that is static presentation only for how it will look . Now the thing wehere I am confuzed is how can i append day to day total steps in corresponding days. Like if it is my first day of the week and i walk 10 steps on monday so the other days should be shown data as 0 steps . if i walk 20 steps on tuesday then it will add 20 steps on tuesday and and all others will be 0 exept monday and tuesday – Ben Smith Nov 04 '19 at 11:16

1 Answers1

2

Assuming that

  • Your week is only 1 week at a time, so no day String repeats in the bar chart and
  • The day Strings in week stay in order (are never randomly sorted)...

You can create a new Int for your Bar Chart's dataSet that has the values of weekdays that have passed and today, with 0 values for upcoming days like this:

func createNewArray() -> [Int] {

    var stepsThisWeek = [Int]()

    // use todays day to find the index of where it appears in var week=[String]()
    if let todayIndex = week.firstIndex(of: getCurrentDayName()) {

        // create indices range of 0 to todayIndex
        let daysSoFarIndices = [Int](0...todayIndex)

        // create new array of var staticSteps=[Int]() at daysSoFarIndices
        stepsThisWeek = daysSoFarIndices.map { staticSteps[$0] }

        //create indices from todayIndex +1 to lastIndex of var staticSteps=[Int]()
        let daysLaterInWeek = [Int](todayIndex..<staticSteps.endIndex)
        //add 0 values for each daysLaterInWeek remaining
        for _ in daysLaterInWeek {
            stepsThisWeek.append(0)
        }
    }
    return stepsThisWeek
}

Then you can call this method where you set your Bar Chart's values like:

setChart(dataPoints: week, values: createNewArray())

Today is Monday, so your bar chart will appear like this.

akaur
  • 365
  • 1
  • 5