How to align labels bottom of the dots
malierbas opened this issue · 0 comments
malierbas commented
`let chart = LineChartView()
chart.border(color: .init(named: "Grey3"), width: 1, radius: 8)
chart.isUserInteractionEnabled = false
chart.legend.enabled = false
// others
let desc = Description()
desc.enabled = false
desc.text = " "
chart.chartDescription = desc
chart.rightAxis.enabled = false
// entries
var entries: [ChartDataEntry] = []
var colors: [NSUIColor] = []
var dats: [String] = []
// data set
let set = LineChartDataSet(entries: entries)
set.drawIconsEnabled = false
set.drawCircleHoleEnabled = false
set.colors = colors
set.circleColors = colors
set.mode = .horizontalBezier
let data = LineChartData(dataSet: set)
chart.data = data
// setup y
let dFormatter = DayAxisValueFormatter()
dFormatter.months = dats
chart.xAxis.valueFormatter = dFormatter
chart.xAxis.labelPosition = .bottom
chart.xAxis.labelCount = dats.count
chart.xAxis.granularity = 1
chart.xAxis.centerAxisLabelsEnabled = true
chart.xAxis.yOffset = 5
chart.xAxis.spaceMin = 5
chart.xAxis.spaceMax = 5
chart.setExtraOffsets(left: 10, top: 5, right: 10, bottom: 5)
chart.minOffset = 20`
My value formatter;
`public class DayAxisValueFormatter: AxisValueFormatter {
weak var chart: BarLineChartViewBase?
var months = ["Jan", "Feb", "Mar",
"Apr", "May", "Jun",
"Jul", "Aug", "Sep",
"Oct", "Nov", "Dec"]
public func stringForValue(_ value: Double, axis: AxisBase?) -> String {
print("string for value data: ", value)
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 ? "" : monthName
}
}
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
}
}
}`