diff --git a/Sources/SwiftUICharts/SharedLineAndBar/Models/ChartViewData.swift b/Sources/SwiftUICharts/SharedLineAndBar/Models/ChartViewData.swift index e6350388..c1d4f4c6 100644 --- a/Sources/SwiftUICharts/SharedLineAndBar/Models/ChartViewData.swift +++ b/Sources/SwiftUICharts/SharedLineAndBar/Models/ChartViewData.swift @@ -65,6 +65,9 @@ public struct ChartViewData { */ var yAxisSpecifier: String = "%.0f" + /// Optional number formatter for the y axis labels when they are `.numeric`. + var yAxisNumberFormatter: NumberFormatter? = nil + /** Width of the y axis title label once it has been rotated. diff --git a/Sources/SwiftUICharts/SharedLineAndBar/Models/Protocols/LineAndBarProtocolsExtentions.swift b/Sources/SwiftUICharts/SharedLineAndBar/Models/Protocols/LineAndBarProtocolsExtentions.swift index 13c0872b..b4a0c6d3 100644 --- a/Sources/SwiftUICharts/SharedLineAndBar/Models/Protocols/LineAndBarProtocolsExtentions.swift +++ b/Sources/SwiftUICharts/SharedLineAndBar/Models/Protocols/LineAndBarProtocolsExtentions.swift @@ -73,7 +73,10 @@ extension CTLineBarChartDataProtocol where Self: GetDataProtocol { They are either auto calculated numbers or array of strings. */ - internal var labelsArray: [String] { self.generateYLabels(self.viewData.yAxisSpecifier) } + internal var labelsArray: [String] { + self.generateYLabels(self.viewData.yAxisSpecifier, + numberFormatter: self.viewData.yAxisNumberFormatter) + } /** Labels to display on the Y axis @@ -89,14 +92,29 @@ extension CTLineBarChartDataProtocol where Self: GetDataProtocol { - specifier: Decimal precision of the labels. - Returns: Array of labels. */ - private func generateYLabels(_ specifier: String) -> [String] { + private func generateYLabels(_ specifier: String, numberFormatter: NumberFormatter?) -> [String] { switch self.chartStyle.yAxisLabelType { case .numeric: let dataRange: Double = self.range let minValue: Double = self.minValue let range: Double = dataRange / Double(self.chartStyle.yAxisNumberOfLabels-1) - let firstLabel = [String(format: specifier, minValue)] - let otherLabels = (1...self.chartStyle.yAxisNumberOfLabels-1).map { String(format: specifier, minValue + range * Double($0)) } + let firstLabel: [String] = { + if let formatter = numberFormatter, + let formattedNumber = formatter.string(from: NSNumber(value:minValue)) { + return [formattedNumber] + } else { + return [String(format: specifier, minValue)] + } + }() + let otherLabels: [String] = (1...self.chartStyle.yAxisNumberOfLabels-1).map { + let value = minValue + range * Double($0) + if let formatter = numberFormatter, + let formattedNumber = formatter.string(from: NSNumber(value: value)) { + return formattedNumber + } else { + return String(format: specifier, value) + } + } let labels = firstLabel + otherLabels return labels case .custom: diff --git a/Sources/SwiftUICharts/SharedLineAndBar/ViewModifiers/YAxisLabels.swift b/Sources/SwiftUICharts/SharedLineAndBar/ViewModifiers/YAxisLabels.swift index f6958558..52252dd4 100644 --- a/Sources/SwiftUICharts/SharedLineAndBar/ViewModifiers/YAxisLabels.swift +++ b/Sources/SwiftUICharts/SharedLineAndBar/ViewModifiers/YAxisLabels.swift @@ -19,6 +19,7 @@ internal struct YAxisLabels: ViewModifier where T: CTLineBarChartDataProtocol internal init( chartData: T, specifier: String, + formatter: NumberFormatter?, colourIndicator: AxisColour ) { self.chartData = chartData @@ -26,6 +27,7 @@ internal struct YAxisLabels: ViewModifier where T: CTLineBarChartDataProtocol self.colourIndicator = colourIndicator chartData.viewData.hasYAxisLabels = true chartData.viewData.yAxisSpecifier = specifier + chartData.viewData.yAxisNumberFormatter = formatter } internal func body(content: Content) -> some View { @@ -81,8 +83,9 @@ extension View { public func yAxisLabels( chartData: T, specifier: String = "%.0f", + formatter: NumberFormatter? = nil, colourIndicator: AxisColour = .none ) -> some View { - self.modifier(YAxisLabels(chartData: chartData, specifier: specifier, colourIndicator: colourIndicator)) + self.modifier(YAxisLabels(chartData: chartData, specifier: specifier, formatter: formatter, colourIndicator: colourIndicator)) } }