123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109 |
- //
- // DayAxisValueFormatter.swift
- // ChartsDemo-iOS
- //
- // Created by Jacob Christie on 2017-07-09.
- // Copyright © 2017 jc. All rights reserved.
- //
- import Foundation
- import Charts
- public class DayAxisValueFormatter: NSObject, AxisValueFormatter {
- weak var chart: BarLineChartViewBase?
- let months = ["Jan", "Feb", "Mar",
- "Apr", "May", "Jun",
- "Jul", "Aug", "Sep",
- "Oct", "Nov", "Dec"]
-
- init(chart: BarLineChartViewBase) {
- self.chart = chart
- }
-
- public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
- let days = Int(value)
- let year = determineYear(forDays: days)
- let month = determineMonth(forDayOfYear: days)
-
- let monthName = months[month % months.count]
- let yearName = "\(year)"
-
- if let chart = chart,
- chart.visibleXRange > 30 * 6 {
- return monthName + yearName
- } else {
- let dayOfMonth = determineDayOfMonth(forDays: days, month: month + 12 * (year - 2016))
- var appendix: String
-
- switch dayOfMonth {
- case 1, 21, 31: appendix = "st"
- case 2, 22: appendix = "nd"
- case 3, 23: appendix = "rd"
- default: appendix = "th"
- }
-
- return dayOfMonth == 0 ? "" : String(format: "%d\(appendix) \(monthName)", dayOfMonth)
- }
- }
-
- private func days(forMonth month: Int, year: Int) -> Int {
- // month is 0-based
- switch month {
- case 1:
- var is29Feb = false
- if year < 1582 {
- is29Feb = (year < 1 ? year + 1 : year) % 4 == 0
- } else if year > 1582 {
- is29Feb = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0)
- }
-
- return is29Feb ? 29 : 28
-
- case 3, 5, 8, 10:
- return 30
-
- default:
- return 31
- }
- }
-
- private func determineMonth(forDayOfYear dayOfYear: Int) -> Int {
- var month = -1
- var days = 0
-
- while days < dayOfYear {
- month += 1
- if month >= 12 {
- month = 0
- }
-
- let year = determineYear(forDays: days)
- days += self.days(forMonth: month, year: year)
- }
-
- return max(month, 0)
- }
-
- private func determineDayOfMonth(forDays days: Int, month: Int) -> Int {
- var count = 0
- var daysForMonth = 0
-
- while count < month {
- let year = determineYear(forDays: days)
- daysForMonth += self.days(forMonth: count % 12, year: year)
- count += 1
- }
-
- return days - daysForMonth
- }
-
- private func determineYear(forDays days: Int) -> Int {
- switch days {
- case ...366: return 2016
- case 367...730: return 2017
- case 731...1094: return 2018
- case 1095...1458: return 2019
- default: return 2020
- }
- }
- }
|