anyone figured out how to customise the Y axis values? id like to be able to process the. axis values and. then display them in the. format id like. eg. "1000" I'd like to display as "1k"
the furthest Ive been able to get is to get the axis to display a static text as the number ie "Y" in the code below. but I haven't been able to access the value. in the code below 'value' seems to be an AxisValue which stores the value but I can't seem to access it in a format I can process.
.chartYAxis {
AxisMarks() { value in
AxisGridLine()
AxisTick()
AxisValueLabel {
Text("Y")
}
}
}
id like to be able to do something like this:
.chartYAxis {
AxisMarks() { value in
AxisGridLine()
AxisTick()
AxisValueLabel {
if value > 1000000000000.0 {
Text("\(value / 1000000000000.0)t")
} else if value > 1000000000.0 {
Text("\(value / 1000000000.0)b")
} else if value > 1000000.0 {
Text("\(value / 1000000.0)m")
} else if value > 1000.0 {
Text("\(value / 1000.0)k")
}
}
}
}
a .stride solution based on Olivers suggestion:
func myChart() -> some View {
var yAxisMaxValue = 23532 //get the min and max values from your data
var yAxisMinValue = -7633 //get the min and max values from your data
let roundedYAxisMaxValue = roundUp(yAxisMaxValue, to: 2)
let roundedYAxisMinValue = roundUp(yAxisMinValue, to: 2)
let strideValue = max(abs(roundedYAxisMaxValue), abs(roundedYAxisMinValue)) / 3.0 //max 3 axis marks above and max 3 below zero
return Chart {
//your chart layout code
}
.chartYAxis {
AxisMarks(values: .stride(by: strideValue)) {
let value = $0.as(Double.self)!
AxisGridLine()
AxisTick()
AxisValueLabel {
Text("\(self.abbreviateAxisValue(string: "\(value)"))")
}
}
}
}
func abbreviateAxisValue(string: String) -> String {
let decimal = Decimal(string: string)
if decimal == nil {
return string
} else {
if abs(decimal!) > 1000000000000.0 {
return "\(decimal! / 1000000000000.0)t"
} else if abs(decimal!) > 1000000000.0 {
return "\(decimal! / 1000000000.0)b"
} else if abs(decimal!) > 1000000.0 {
return "\(decimal! / 1000000.0)m"
} else if abs(decimal!) > 1000.0 {
return "\(decimal! / 1000.0)k"
} else {
return "\(decimal!)"
}
}
}
//round up to x significant digits
func roundUp(_ num: Double, to places: Int) -> Double {
let p = log10(abs(num))
let f = pow(10, p.rounded(.up) - Double(places) + 1)
let rnum = (num / f).rounded(.up) * f
return rnum
}