diff --git a/Charts.xcodeproj/project.pbxproj b/Charts.xcodeproj/project.pbxproj index 00cdf1118e..ef673fe70e 100644 --- a/Charts.xcodeproj/project.pbxproj +++ b/Charts.xcodeproj/project.pbxproj @@ -88,7 +88,7 @@ 83BBAF3EDC31FD452F8BF1DB /* RadarChartDataSetProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2EAD807534620E3B53327F04 /* RadarChartDataSetProtocol.swift */; }; 846AC09831FA93F66732591B /* YAxisRendererHorizontalBarChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = EAE417AAA0FCA0DD00E77489 /* YAxisRendererHorizontalBarChart.swift */; }; 8A463E2947F211C594CA5E95 /* TransformerHorizontalBarChart.swift in Sources */ = {isa = PBXBuildFile; fileRef = 324C9127B53A8D39C8B49277 /* TransformerHorizontalBarChart.swift */; }; - 8A9FF54E2075A9047CC8E953 /* IShapeRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1D3D13180C2E3893A82546 /* IShapeRenderer.swift */; }; + 8A9FF54E2075A9047CC8E953 /* ShapeRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA1D3D13180C2E3893A82546 /* ShapeRenderer.swift */; }; 8BCCD709AACC565613D9DA68 /* CandleStickChartRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD5C6D20243EC2F19069AACD /* CandleStickChartRenderer.swift */; }; 8E1192F7A7152E9DA92C56A9 /* ChartUtilsTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 7AB9062A28AAB9469752A954 /* ChartUtilsTests.swift */; }; 8EF7B3FBE37F72CC030CD865 /* SquareShapeRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 32FC01A016DFF1BA73AF9182 /* SquareShapeRenderer.swift */; }; @@ -139,10 +139,10 @@ EAEA60D22CA8C1B7E18D3F7D /* ChartDataEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = F22750328058DEC2F019646F /* ChartDataEntry.swift */; }; EB56849433A76B08606B73EB /* ScatterChartDataSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = CB1DD1A0F64266A10EE94194 /* ScatterChartDataSet.swift */; }; ECE7EAE7179A7F57CE9BBD8F /* Legend.swift in Sources */ = {isa = PBXBuildFile; fileRef = E64A75540C627E09080B402A /* Legend.swift */; }; - ECECC58CEF03B1718F8267E8 /* AxisRendererBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = C75935E899183DDFA181E2CC /* AxisRendererBase.swift */; }; + ECECC58CEF03B1718F8267E8 /* AxisRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = C75935E899183DDFA181E2CC /* AxisRenderer.swift */; }; F100D68395F169B93590FA96 /* HorizontalBarChartRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 539382766378B702660FDFB2 /* HorizontalBarChartRenderer.swift */; }; F103D90FC5DEEA0D7BB4407E /* ChevronUpShapeRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = AA70259ED16FF80D8EEB0F94 /* ChevronUpShapeRenderer.swift */; }; - F37B07008B8AE7F3909FFB9C /* ChartDataRendererBase.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0216EDC6A1FE272F4EB19FCF /* ChartDataRendererBase.swift */; }; + F37B07008B8AE7F3909FFB9C /* DataRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 0216EDC6A1FE272F4EB19FCF /* DataRenderer.swift */; }; F5A209116FAC68F5903D0B46 /* ChartAnimationEasing.swift in Sources */ = {isa = PBXBuildFile; fileRef = DFB762958EE8E6521563665D /* ChartAnimationEasing.swift */; }; F744C510DA9B85C228BBB335 /* DefaultFillFormatter.swift in Sources */ = {isa = PBXBuildFile; fileRef = D6C1BEFDF17404666C7B6054 /* DefaultFillFormatter.swift */; }; F941C88BF814DF51C465CB95 /* LineChartDataSetProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 429E88F2729735DC092EE556 /* LineChartDataSetProtocol.swift */; }; @@ -164,7 +164,7 @@ /* Begin PBXFileReference section */ 0108D5925E21A47DA36A66AA /* BarChartData.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BarChartData.swift; path = Source/Charts/Data/Implementations/Standard/BarChartData.swift; sourceTree = ""; }; - 0216EDC6A1FE272F4EB19FCF /* ChartDataRendererBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChartDataRendererBase.swift; path = Source/Charts/Renderers/ChartDataRendererBase.swift; sourceTree = ""; }; + 0216EDC6A1FE272F4EB19FCF /* DataRenderer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = DataRenderer.swift; path = Source/Charts/Renderers/DataRenderer.swift; sourceTree = ""; }; 04F7B9DF1F2D66E7279771D4 /* PieRadarHighlighter.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = PieRadarHighlighter.swift; path = Source/Charts/Highlight/PieRadarHighlighter.swift; sourceTree = ""; }; 0619A877C69A95ECCC440A44 /* LineChartView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LineChartView.swift; path = Source/Charts/Charts/LineChartView.swift; sourceTree = ""; }; 064989451F5C99C7006E8BB3 /* Snapshot.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = Snapshot.swift; path = Tests/Charts/Snapshot.swift; sourceTree = ""; }; @@ -277,7 +277,7 @@ C52E8344160B5E689DA3C25C /* ChevronDownShapeRenderer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChevronDownShapeRenderer.swift; path = Source/Charts/Renderers/Scatter/ChevronDownShapeRenderer.swift; sourceTree = ""; }; C574E1BC7E12D937A5471EF8 /* Info.plist */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.plist.xml; name = Info.plist; path = "Tests/Supporting Files/Info.plist"; sourceTree = ""; }; C58BD7B14BEA440783ED8D2B /* LineScatterCandleRadarChartDataSet.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LineScatterCandleRadarChartDataSet.swift; path = Source/Charts/Data/Implementations/Standard/LineScatterCandleRadarChartDataSet.swift; sourceTree = ""; }; - C75935E899183DDFA181E2CC /* AxisRendererBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AxisRendererBase.swift; path = Source/Charts/Renderers/AxisRendererBase.swift; sourceTree = ""; }; + C75935E899183DDFA181E2CC /* AxisRenderer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = AxisRenderer.swift; path = Source/Charts/Renderers/AxisRenderer.swift; sourceTree = ""; }; C8C9A105A7DB64F39DDA648B /* ComponentBase.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ComponentBase.swift; path = Source/Charts/Components/ComponentBase.swift; sourceTree = ""; }; C8FB6219B143F8F7DA762950 /* TriangleShapeRenderer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = TriangleShapeRenderer.swift; path = Source/Charts/Renderers/Scatter/TriangleShapeRenderer.swift; sourceTree = ""; }; C9FE42E868A225C116537368 /* ChartBaseDataSet.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChartBaseDataSet.swift; path = Source/Charts/Data/Implementations/ChartBaseDataSet.swift; sourceTree = ""; }; @@ -303,7 +303,7 @@ F6227A646166E248F90F86AD /* ChartColorTemplates.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChartColorTemplates.swift; path = Source/Charts/Utils/ChartColorTemplates.swift; sourceTree = ""; }; F6DEBFAB1D73E944ED430B4F /* ChartLimitLine.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ChartLimitLine.swift; path = Source/Charts/Components/ChartLimitLine.swift; sourceTree = ""; }; F715DB2C56C9E0615542625B /* LegendRenderer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = LegendRenderer.swift; path = Source/Charts/Renderers/LegendRenderer.swift; sourceTree = ""; }; - FA1D3D13180C2E3893A82546 /* IShapeRenderer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = IShapeRenderer.swift; path = Source/Charts/Renderers/Scatter/IShapeRenderer.swift; sourceTree = ""; }; + FA1D3D13180C2E3893A82546 /* ShapeRenderer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ShapeRenderer.swift; path = Source/Charts/Renderers/Scatter/ShapeRenderer.swift; sourceTree = ""; }; FA7BDB22C97F39A4B33E38A7 /* ViewPortJob.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ViewPortJob.swift; path = Source/Charts/Jobs/ViewPortJob.swift; sourceTree = ""; }; FB3A4F5987E58F3E5BE855F9 /* ZoomViewJob.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ZoomViewJob.swift; path = Source/Charts/Jobs/ZoomViewJob.swift; sourceTree = ""; }; FB92A80F861C1362EED8D946 /* YAxis.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = YAxis.swift; path = Source/Charts/Components/YAxis.swift; sourceTree = ""; }; @@ -369,6 +369,40 @@ name = Source; sourceTree = ""; }; + 2227EA571FF1F219007D98D9 /* AxisRenderers */ = { + isa = PBXGroup; + children = ( + C75935E899183DDFA181E2CC /* AxisRenderer.swift */, + 1C02C3AF5C92FCFC18224C35 /* XAxisRenderer.swift */, + 1F3D55A7E6176D52DC957D27 /* XAxisRendererHorizontalBarChart.swift */, + BC19DC2434D65FFB446A61B7 /* XAxisRendererRadarChart.swift */, + 688B80F1AA88AE54152BE768 /* YAxisRenderer.swift */, + EAE417AAA0FCA0DD00E77489 /* YAxisRendererHorizontalBarChart.swift */, + AA5A16F4A382813C4FE8BDF9 /* YAxisRendererRadarChart.swift */, + ); + name = AxisRenderers; + sourceTree = ""; + }; + 2227EA581FF1F224007D98D9 /* ChartRenderers */ = { + isa = PBXGroup; + children = ( + 0216EDC6A1FE272F4EB19FCF /* DataRenderer.swift */, + 75F279974FE650E57A061B09 /* BarChartRenderer.swift */, + 5B1C588E9DF6FFD56D7ADF8E /* BarLineScatterCandleBubbleRenderer.swift */, + 2194AA554712E6BA2677F114 /* BubbleChartRenderer.swift */, + BD5C6D20243EC2F19069AACD /* CandleStickChartRenderer.swift */, + 52265C1B343CCC41AF2300E3 /* CombinedChartRenderer.swift */, + 539382766378B702660FDFB2 /* HorizontalBarChartRenderer.swift */, + 0DABDBBCCE6B3620C967F04A /* LineChartRenderer.swift */, + 105FFC9D3773A9C7A60A897F /* LineRadarRenderer.swift */, + 923206233CA89FD03565FF87 /* LineScatterCandleRadarRenderer.swift */, + 46D8013D44629521B1746364 /* PieChartRenderer.swift */, + 7AC9C3D69ACB5BDE22421E15 /* RadarChartRenderer.swift */, + 80D5B764EC0AE1E17E55DC67 /* ScatterChartRenderer.swift */, + ); + name = ChartRenderers; + sourceTree = ""; + }; 2647844720BC6574A544A337 /* Charts */ = { isa = PBXGroup; children = ( @@ -613,29 +647,11 @@ E7589D3E7C2BD2449960AD59 /* Renderers */ = { isa = PBXGroup; children = ( - C75935E899183DDFA181E2CC /* AxisRendererBase.swift */, - 75F279974FE650E57A061B09 /* BarChartRenderer.swift */, - 5B1C588E9DF6FFD56D7ADF8E /* BarLineScatterCandleBubbleRenderer.swift */, - 2194AA554712E6BA2677F114 /* BubbleChartRenderer.swift */, - BD5C6D20243EC2F19069AACD /* CandleStickChartRenderer.swift */, - 0216EDC6A1FE272F4EB19FCF /* ChartDataRendererBase.swift */, - 52265C1B343CCC41AF2300E3 /* CombinedChartRenderer.swift */, - 539382766378B702660FDFB2 /* HorizontalBarChartRenderer.swift */, F715DB2C56C9E0615542625B /* LegendRenderer.swift */, - 0DABDBBCCE6B3620C967F04A /* LineChartRenderer.swift */, - 105FFC9D3773A9C7A60A897F /* LineRadarRenderer.swift */, - 923206233CA89FD03565FF87 /* LineScatterCandleRadarRenderer.swift */, - 46D8013D44629521B1746364 /* PieChartRenderer.swift */, - 7AC9C3D69ACB5BDE22421E15 /* RadarChartRenderer.swift */, 6F66B32AD8A878CBD6DB6ED2 /* Renderer.swift */, - F7059584CB30EF419CFB3335 /* Scatter */, - 80D5B764EC0AE1E17E55DC67 /* ScatterChartRenderer.swift */, - 1C02C3AF5C92FCFC18224C35 /* XAxisRenderer.swift */, - 1F3D55A7E6176D52DC957D27 /* XAxisRendererHorizontalBarChart.swift */, - BC19DC2434D65FFB446A61B7 /* XAxisRendererRadarChart.swift */, - 688B80F1AA88AE54152BE768 /* YAxisRenderer.swift */, - EAE417AAA0FCA0DD00E77489 /* YAxisRendererHorizontalBarChart.swift */, - AA5A16F4A382813C4FE8BDF9 /* YAxisRendererRadarChart.swift */, + 2227EA571FF1F219007D98D9 /* AxisRenderers */, + 2227EA581FF1F224007D98D9 /* ChartRenderers */, + F7059584CB30EF419CFB3335 /* ShapeRenderer */, ); name = Renderers; sourceTree = ""; @@ -649,19 +665,19 @@ name = "Supporting Files"; sourceTree = ""; }; - F7059584CB30EF419CFB3335 /* Scatter */ = { + F7059584CB30EF419CFB3335 /* ShapeRenderer */ = { isa = PBXGroup; children = ( C52E8344160B5E689DA3C25C /* ChevronDownShapeRenderer.swift */, AA70259ED16FF80D8EEB0F94 /* ChevronUpShapeRenderer.swift */, ECE1B1623D3AF69CECAE8562 /* CircleShapeRenderer.swift */, 823F7DB281C6C6F069A69605 /* CrossShapeRenderer.swift */, - FA1D3D13180C2E3893A82546 /* IShapeRenderer.swift */, + FA1D3D13180C2E3893A82546 /* ShapeRenderer.swift */, 32FC01A016DFF1BA73AF9182 /* SquareShapeRenderer.swift */, C8FB6219B143F8F7DA762950 /* TriangleShapeRenderer.swift */, 23D35CF6F9177D77B6B97AE1 /* XShapeRenderer.swift */, ); - name = Scatter; + name = ShapeRenderer; sourceTree = ""; }; /* End PBXGroup section */ @@ -901,12 +917,12 @@ 02A6E6E1A82A27A66B8D08C4 /* MoveViewJob.swift in Sources */, 9400725714D0DA707DDECD2E /* ViewPortJob.swift in Sources */, AEE9C4E4AC02B8FB3CD21975 /* ZoomViewJob.swift in Sources */, - ECECC58CEF03B1718F8267E8 /* AxisRendererBase.swift in Sources */, + ECECC58CEF03B1718F8267E8 /* AxisRenderer.swift in Sources */, 23FA50B2730D8C7ACA091C4F /* BarChartRenderer.swift in Sources */, 219192CA6B4895319AB49DCA /* BarLineScatterCandleBubbleRenderer.swift in Sources */, 56E0F5EA9255B9B92876E040 /* BubbleChartRenderer.swift in Sources */, 8BCCD709AACC565613D9DA68 /* CandleStickChartRenderer.swift in Sources */, - F37B07008B8AE7F3909FFB9C /* ChartDataRendererBase.swift in Sources */, + F37B07008B8AE7F3909FFB9C /* DataRenderer.swift in Sources */, 05253AFC448C107DEF54C2FE /* CombinedChartRenderer.swift in Sources */, F100D68395F169B93590FA96 /* HorizontalBarChartRenderer.swift in Sources */, 2B821AAC3EBD60A73EACBCE6 /* LegendRenderer.swift in Sources */, @@ -920,7 +936,7 @@ F103D90FC5DEEA0D7BB4407E /* ChevronUpShapeRenderer.swift in Sources */, B85DEB06B4C1AFFC8A0E3295 /* CircleShapeRenderer.swift in Sources */, 0529DD51622C8769C1121F90 /* CrossShapeRenderer.swift in Sources */, - 8A9FF54E2075A9047CC8E953 /* IShapeRenderer.swift in Sources */, + 8A9FF54E2075A9047CC8E953 /* ShapeRenderer.swift in Sources */, 8EF7B3FBE37F72CC030CD865 /* SquareShapeRenderer.swift in Sources */, 8F4B1A9060472764073DFA0B /* TriangleShapeRenderer.swift in Sources */, 93A94E1FF55041A6032891FE /* XShapeRenderer.swift in Sources */, diff --git a/Source/Charts/Charts/BarLineChartViewBase.swift b/Source/Charts/Charts/BarLineChartViewBase.swift index 406a96f414..1a438f00c5 100644 --- a/Source/Charts/Charts/BarLineChartViewBase.swift +++ b/Source/Charts/Charts/BarLineChartViewBase.swift @@ -106,10 +106,10 @@ open class BarLineChartViewBase: ChartViewBase, BarLineScatterCandleBubbleChartD _leftAxisTransformer = Transformer(viewPortHandler: _viewPortHandler) _rightAxisTransformer = Transformer(viewPortHandler: _viewPortHandler) - _leftYAxisRenderer = YAxisRenderer(viewPortHandler: _viewPortHandler, yAxis: _leftAxis, transformer: _leftAxisTransformer) - _rightYAxisRenderer = YAxisRenderer(viewPortHandler: _viewPortHandler, yAxis: _rightAxis, transformer: _rightAxisTransformer) + _leftYAxisRenderer = YAxisRenderer(viewPortHandler: _viewPortHandler, axis: _leftAxis, transformer: _leftAxisTransformer) + _rightYAxisRenderer = YAxisRenderer(viewPortHandler: _viewPortHandler, axis: _rightAxis, transformer: _rightAxisTransformer) - _xAxisRenderer = XAxisRenderer(viewPortHandler: _viewPortHandler, xAxis: _xAxis, transformer: _leftAxisTransformer) + _xAxisRenderer = XAxisRenderer(viewPortHandler: _viewPortHandler, axis: _xAxis, transformer: _leftAxisTransformer) self.highlighter = ChartHighlighter(chart: self) diff --git a/Source/Charts/Charts/HorizontalBarChartView.swift b/Source/Charts/Charts/HorizontalBarChartView.swift index 277d37648c..e36567bb8c 100644 --- a/Source/Charts/Charts/HorizontalBarChartView.swift +++ b/Source/Charts/Charts/HorizontalBarChartView.swift @@ -27,9 +27,9 @@ open class HorizontalBarChartView: BarChartView _rightAxisTransformer = TransformerHorizontalBarChart(viewPortHandler: _viewPortHandler) renderer = HorizontalBarChartRenderer(dataProvider: self, animator: _animator, viewPortHandler: _viewPortHandler) - _leftYAxisRenderer = YAxisRendererHorizontalBarChart(viewPortHandler: _viewPortHandler, yAxis: _leftAxis, transformer: _leftAxisTransformer) - _rightYAxisRenderer = YAxisRendererHorizontalBarChart(viewPortHandler: _viewPortHandler, yAxis: _rightAxis, transformer: _rightAxisTransformer) - _xAxisRenderer = XAxisRendererHorizontalBarChart(viewPortHandler: _viewPortHandler, xAxis: _xAxis, transformer: _leftAxisTransformer, chart: self) + _leftYAxisRenderer = YAxisRendererHorizontalBarChart(viewPortHandler: _viewPortHandler, axis: _leftAxis, transformer: _leftAxisTransformer) + _rightYAxisRenderer = YAxisRendererHorizontalBarChart(viewPortHandler: _viewPortHandler, axis: _rightAxis, transformer: _rightAxisTransformer) + _xAxisRenderer = XAxisRendererHorizontalBarChart(viewPortHandler: _viewPortHandler, axis: _xAxis, transformer: _leftAxisTransformer, chart: self) self.highlighter = HorizontalBarHighlighter(chart: self) } diff --git a/Source/Charts/Charts/RadarChartView.swift b/Source/Charts/Charts/RadarChartView.swift index 2b89fbae69..0d1143bead 100644 --- a/Source/Charts/Charts/RadarChartView.swift +++ b/Source/Charts/Charts/RadarChartView.swift @@ -62,8 +62,8 @@ open class RadarChartView: PieRadarChartViewBase renderer = RadarChartRenderer(chart: self, animator: _animator, viewPortHandler: _viewPortHandler) - _yAxisRenderer = YAxisRendererRadarChart(viewPortHandler: _viewPortHandler, yAxis: _yAxis, chart: self) - _xAxisRenderer = XAxisRendererRadarChart(viewPortHandler: _viewPortHandler, xAxis: _xAxis, chart: self) + _yAxisRenderer = YAxisRendererRadarChart(viewPortHandler: _viewPortHandler, axis: _yAxis, chart: self) + _xAxisRenderer = XAxisRendererRadarChart(viewPortHandler: _viewPortHandler, axis: _xAxis, chart: self) self.highlighter = RadarHighlighter(chart: self) } diff --git a/Source/Charts/Data/Implementations/Standard/ScatterChartDataSet.swift b/Source/Charts/Data/Implementations/Standard/ScatterChartDataSet.swift index 1f60c8c126..b7d1658349 100644 --- a/Source/Charts/Data/Implementations/Standard/ScatterChartDataSet.swift +++ b/Source/Charts/Data/Implementations/Standard/ScatterChartDataSet.swift @@ -39,7 +39,7 @@ open class ScatterChartDataSet: LineScatterCandleRadarChartDataSet, ScatterChart open var scatterShapeHoleColor: NSUIColor? = nil /// Sets the ScatterShape this DataSet should be drawn with. - /// This will search for an available IShapeRenderer and set this renderer for the DataSet + /// This will search for an available ShapeRenderer and set this renderer for the DataSet @objc open func setScatterShape(_ shape: Shape) { self.shapeRenderer = ScatterChartDataSet.renderer(forShape: shape) @@ -48,9 +48,9 @@ open class ScatterChartDataSet: LineScatterCandleRadarChartDataSet, ScatterChart /// The IShapeRenderer responsible for rendering this DataSet. /// This can also be used to set a custom IShapeRenderer aside from the default ones. /// **default**: `SquareShapeRenderer` - open var shapeRenderer: IShapeRenderer? = SquareShapeRenderer() + open var shapeRenderer: ShapeRenderer? = SquareShapeRenderer() - @objc open class func renderer(forShape shape: Shape) -> IShapeRenderer + @objc open class func renderer(forShape shape: Shape) -> ShapeRenderer { switch shape { diff --git a/Source/Charts/Data/Interfaces/ScatterChartDataSetProtocol.swift b/Source/Charts/Data/Interfaces/ScatterChartDataSetProtocol.swift index d101e22af3..0fa23662ae 100644 --- a/Source/Charts/Data/Interfaces/ScatterChartDataSetProtocol.swift +++ b/Source/Charts/Data/Interfaces/ScatterChartDataSetProtocol.swift @@ -32,5 +32,5 @@ public protocol ScatterChartDataSetProtocol: LineScatterCandleRadarChartDataSetP var scatterShapeHoleColor: NSUIColor? { get } /// - returns: The IShapeRenderer responsible for rendering this DataSet. - var shapeRenderer: IShapeRenderer? { get } + var shapeRenderer: ShapeRenderer? { get } } diff --git a/Source/Charts/Renderers/AxisRenderer.swift b/Source/Charts/Renderers/AxisRenderer.swift new file mode 100644 index 0000000000..35b1ddf72d --- /dev/null +++ b/Source/Charts/Renderers/AxisRenderer.swift @@ -0,0 +1,45 @@ +// +// AxisRenderer.swift +// Charts +// +// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda +// A port of MPAndroidChart for iOS +// Licensed under Apache License 2.0 +// +// https://github.com/danielgindi/Charts +// + +import Foundation +import CoreGraphics + + +public protocol AxisRenderer: Renderer { + + associatedtype Axis: AxisBase + + /// base axis this axis renderer works with + var axis: Axis { get } + + /// transformer to transform values to screen pixels and return + var transformer: Transformer? { get } + + /// Draws the axis labels on the specified context + func renderAxisLabels(context: CGContext) + + /// Draws the grid lines belonging to the axis. + func renderGridLines(context: CGContext) + + /// Draws the line that goes alongside the axis. + func renderAxisLine(context: CGContext) + + /// Draws the LimitLines associated with this axis to the screen. + func renderLimitLines(context: CGContext) + + /// Computes the axis values. + /// - parameter min: the minimum value in the data object for this axis + /// - parameter max: the maximum value in the data object for this axis + func computeAxis(min: Double, max: Double, inverted: Bool) + + /// Sets up the axis values. Computes the desired number of labels between the two given extremes. + func computeAxisValues(min: Double, max: Double) +} diff --git a/Source/Charts/Renderers/AxisRendererBase.swift b/Source/Charts/Renderers/AxisRendererBase.swift deleted file mode 100644 index bd1c6aa466..0000000000 --- a/Source/Charts/Renderers/AxisRendererBase.swift +++ /dev/null @@ -1,211 +0,0 @@ -// -// AxisRendererBase.swift -// Charts -// -// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda -// A port of MPAndroidChart for iOS -// Licensed under Apache License 2.0 -// -// https://github.com/danielgindi/Charts -// - -import Foundation -import CoreGraphics - -@objc(ChartAxisRendererBase) -open class AxisRendererBase: Renderer -{ - /// base axis this axis renderer works with - @objc open var axis: AxisBase? - - /// transformer to transform values to screen pixels and return - @objc open var transformer: Transformer? - - @objc public init(viewPortHandler: ViewPortHandler, transformer: Transformer?, axis: AxisBase?) - { - super.init(viewPortHandler: viewPortHandler) - - self.transformer = transformer - self.axis = axis - } - - /// Draws the axis labels on the specified context - @objc open func renderAxisLabels(context: CGContext) - { - fatalError("renderAxisLabels() cannot be called on AxisRendererBase") - } - - /// Draws the grid lines belonging to the axis. - @objc open func renderGridLines(context: CGContext) - { - fatalError("renderGridLines() cannot be called on AxisRendererBase") - } - - /// Draws the line that goes alongside the axis. - @objc open func renderAxisLine(context: CGContext) - { - fatalError("renderAxisLine() cannot be called on AxisRendererBase") - } - - /// Draws the LimitLines associated with this axis to the screen. - @objc open func renderLimitLines(context: CGContext) - { - fatalError("renderLimitLines() cannot be called on AxisRendererBase") - } - - /// Computes the axis values. - /// - parameter min: the minimum value in the data object for this axis - /// - parameter max: the maximum value in the data object for this axis - @objc open func computeAxis(min: Double, max: Double, inverted: Bool) - { - var min = min, max = max - - if let transformer = self.transformer - { - // calculate the starting and entry point of the y-labels (depending on zoom / contentrect bounds) - if viewPortHandler.contentWidth > 10.0 && !viewPortHandler.isFullyZoomedOutY - { - let p1 = transformer.valueForTouchPoint(CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentTop)) - let p2 = transformer.valueForTouchPoint(CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentBottom)) - - if !inverted - { - min = Double(p2.y) - max = Double(p1.y) - } - else - { - min = Double(p1.y) - max = Double(p2.y) - } - } - } - - computeAxisValues(min: min, max: max) - } - - /// Sets up the axis values. Computes the desired number of labels between the two given extremes. - @objc open func computeAxisValues(min: Double, max: Double) - { - guard let axis = self.axis else { return } - - let yMin = min - let yMax = max - - let labelCount = axis.labelCount - let range = abs(yMax - yMin) - - if labelCount == 0 || range <= 0 || range.isInfinite - { - axis.entries = [Double]() - axis.centeredEntries = [Double]() - return - } - - // Find out how much spacing (in y value space) between axis values - let rawInterval = range / Double(labelCount) - var interval = ChartUtils.roundToNextSignificant(number: Double(rawInterval)) - - // If granularity is enabled, then do not allow the interval to go below specified granularity. - // This is used to avoid repeated values when rounding values for display. - if axis.granularityEnabled - { - interval = interval < axis.granularity ? axis.granularity : interval - } - - // Normalize interval - let intervalMagnitude = ChartUtils.roundToNextSignificant(number: pow(10.0, Double(Int(log10(interval))))) - let intervalSigDigit = Int(interval / intervalMagnitude) - if intervalSigDigit > 5 - { - // Use one order of magnitude higher, to avoid intervals like 0.9 or 90 - interval = floor(10.0 * Double(intervalMagnitude)) - } - - var n = axis.centerAxisLabelsEnabled ? 1 : 0 - - // force label count - if axis.isForceLabelsEnabled - { - interval = Double(range) / Double(labelCount - 1) - - // Ensure stops contains at least n elements. - axis.entries.removeAll(keepingCapacity: true) - axis.entries.reserveCapacity(labelCount) - - var v = yMin - - for _ in 0 ..< labelCount - { - axis.entries.append(v) - v += interval - } - - n = labelCount - } - else - { - // no forced count - - var first = interval == 0.0 ? 0.0 : ceil(yMin / interval) * interval - - if axis.centerAxisLabelsEnabled - { - first -= interval - } - - let last = interval == 0.0 ? 0.0 : ChartUtils.nextUp(floor(yMax / interval) * interval) - - if interval != 0.0 && last != first - { - for _ in stride(from: first, through: last, by: interval) - { - n += 1 - } - } - - // Ensure stops contains at least n elements. - axis.entries.removeAll(keepingCapacity: true) - axis.entries.reserveCapacity(labelCount) - - var f = first - var i = 0 - while i < n - { - if f == 0.0 - { - // Fix for IEEE negative zero case (Where value == -0.0, and 0.0 == -0.0) - f = 0.0 - } - - axis.entries.append(Double(f)) - - f += interval - i += 1 - } - } - - // set decimals - if interval < 1 - { - axis.decimals = Int(ceil(-log10(interval))) - } - else - { - axis.decimals = 0 - } - - if axis.centerAxisLabelsEnabled - { - axis.centeredEntries.reserveCapacity(n) - axis.centeredEntries.removeAll() - - let offset: Double = interval / 2.0 - - for i in 0 ..< n - { - axis.centeredEntries.append(axis.entries[i] + offset) - } - } - } -} diff --git a/Source/Charts/Renderers/BarLineScatterCandleBubbleRenderer.swift b/Source/Charts/Renderers/BarLineScatterCandleBubbleRenderer.swift index 1a2ad8ce46..4bfd560f87 100644 --- a/Source/Charts/Renderers/BarLineScatterCandleBubbleRenderer.swift +++ b/Source/Charts/Renderers/BarLineScatterCandleBubbleRenderer.swift @@ -13,15 +13,30 @@ import Foundation import CoreGraphics @objc(BarLineScatterCandleBubbleChartRenderer) -open class BarLineScatterCandleBubbleRenderer: DataRenderer +open class BarLineScatterCandleBubbleRenderer: NSObject, DataRenderer { + public let viewPortHandler: ViewPortHandler + + public let animator: Animator + internal var _xBounds = XBounds() // Reusable XBounds object - public override init(animator: Animator, viewPortHandler: ViewPortHandler) + public init(animator: Animator, viewPortHandler: ViewPortHandler) { - super.init(animator: animator, viewPortHandler: viewPortHandler) + self.viewPortHandler = viewPortHandler + self.animator = animator + + super.init() } - + + open func drawData(context: CGContext) { } + + open func drawValues(context: CGContext) { } + + open func drawExtras(context: CGContext) { } + + open func drawHighlighted(context: CGContext, indices: [Highlight]) { } + /// Checks if the provided entry object is in bounds for drawing considering the current animation phase. internal func isInBoundsX(entry e: ChartDataEntry, dataSet: BarLineScatterCandleBubbleChartDataSetProtocol) -> Bool { @@ -44,6 +59,14 @@ open class BarLineScatterCandleBubbleRenderer: DataRenderer return set.isVisible && (set.isDrawValuesEnabled || set.isDrawIconsEnabled) } + open func initBuffers() { } + + open func isDrawingValuesAllowed(dataProvider: ChartDataProvider?) -> Bool + { + guard let data = dataProvider?.data else { return false } + return data.entryCount < Int(CGFloat(dataProvider?.maxVisibleCount ?? 0) * viewPortHandler.scaleX) + } + /// Class representing the bounds of the current viewport in terms of indices in the values array of a DataSet. open class XBounds { diff --git a/Source/Charts/Renderers/ChartDataRendererBase.swift b/Source/Charts/Renderers/ChartDataRendererBase.swift deleted file mode 100644 index 024516aa15..0000000000 --- a/Source/Charts/Renderers/ChartDataRendererBase.swift +++ /dev/null @@ -1,59 +0,0 @@ -// -// DataRenderer.swift -// Charts -// -// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda -// A port of MPAndroidChart for iOS -// Licensed under Apache License 2.0 -// -// https://github.com/danielgindi/Charts -// - -import Foundation -import CoreGraphics - -@objc(ChartDataRendererBase) -open class DataRenderer: Renderer -{ - @objc open let animator: Animator - - @objc public init(animator: Animator, viewPortHandler: ViewPortHandler) - { - self.animator = animator - - super.init(viewPortHandler: viewPortHandler) - } - - @objc open func drawData(context: CGContext) - { - fatalError("drawData() cannot be called on DataRenderer") - } - - @objc open func drawValues(context: CGContext) - { - fatalError("drawValues() cannot be called on DataRenderer") - } - - @objc open func drawExtras(context: CGContext) - { - fatalError("drawExtras() cannot be called on DataRenderer") - } - - /// Draws all highlight indicators for the values that are currently highlighted. - /// - /// - parameter indices: the highlighted values - @objc open func drawHighlighted(context: CGContext, indices: [Highlight]) - { - fatalError("drawHighlighted() cannot be called on DataRenderer") - } - - /// An opportunity for initializing internal buffers used for rendering with a new size. - /// Since this might do memory allocations, it should only be called if necessary. - @objc open func initBuffers() { } - - @objc open func isDrawingValuesAllowed(dataProvider: ChartDataProvider?) -> Bool - { - guard let data = dataProvider?.data else { return false } - return data.entryCount < Int(CGFloat(dataProvider?.maxVisibleCount ?? 0) * viewPortHandler.scaleX) - } -} diff --git a/Source/Charts/Renderers/CombinedChartRenderer.swift b/Source/Charts/Renderers/CombinedChartRenderer.swift index d38ccb5f7a..529561878f 100644 --- a/Source/Charts/Renderers/CombinedChartRenderer.swift +++ b/Source/Charts/Renderers/CombinedChartRenderer.swift @@ -12,8 +12,11 @@ import Foundation import CoreGraphics -open class CombinedChartRenderer: DataRenderer +open class CombinedChartRenderer: NSObject, DataRenderer { + public let viewPortHandler: ViewPortHandler + public let animator: Animator + @objc open weak var chart: CombinedChartView? /// if set to true, all values are drawn above their bars, instead of below their top @@ -28,9 +31,11 @@ open class CombinedChartRenderer: DataRenderer @objc public init(chart: CombinedChartView, animator: Animator, viewPortHandler: ViewPortHandler) { - super.init(animator: animator, viewPortHandler: viewPortHandler) - self.chart = chart + self.viewPortHandler = viewPortHandler + self.animator = animator + + super.init() createRenderers() } @@ -85,7 +90,7 @@ open class CombinedChartRenderer: DataRenderer } - open override func initBuffers() + open func initBuffers() { for renderer in _renderers { @@ -93,7 +98,7 @@ open class CombinedChartRenderer: DataRenderer } } - open override func drawData(context: CGContext) + open func drawData(context: CGContext) { for renderer in _renderers { @@ -101,7 +106,7 @@ open class CombinedChartRenderer: DataRenderer } } - open override func drawValues(context: CGContext) + open func drawValues(context: CGContext) { for renderer in _renderers { @@ -109,7 +114,7 @@ open class CombinedChartRenderer: DataRenderer } } - open override func drawExtras(context: CGContext) + open func drawExtras(context: CGContext) { for renderer in _renderers { @@ -117,7 +122,7 @@ open class CombinedChartRenderer: DataRenderer } } - open override func drawHighlighted(context: CGContext, indices: [Highlight]) + open func drawHighlighted(context: CGContext, indices: [Highlight]) { for renderer in _renderers { @@ -152,6 +157,12 @@ open class CombinedChartRenderer: DataRenderer } } + open func isDrawingValuesAllowed(dataProvider: ChartDataProvider?) -> Bool + { + guard let data = dataProvider?.data else { return false } + return data.entryCount < Int(CGFloat(dataProvider?.maxVisibleCount ?? 0) * viewPortHandler.scaleX) + } + /// - returns: The sub-renderer object at the specified index. @objc open func getSubRenderer(index: Int) -> DataRenderer? { diff --git a/Source/Charts/Renderers/DataRenderer.swift b/Source/Charts/Renderers/DataRenderer.swift new file mode 100644 index 0000000000..bea371e428 --- /dev/null +++ b/Source/Charts/Renderers/DataRenderer.swift @@ -0,0 +1,36 @@ +// +// DataRenderer.swift +// Charts +// +// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda +// A port of MPAndroidChart for iOS +// Licensed under Apache License 2.0 +// +// https://github.com/danielgindi/Charts +// + +import Foundation +import CoreGraphics + +@objc(ChartDataRenderer) +public protocol DataRenderer: Renderer +{ + var animator: Animator { get } + + func drawData(context: CGContext) + + func drawValues(context: CGContext) + + func drawExtras(context: CGContext) + + /// Draws all highlight indicators for the values that are currently highlighted. + /// + /// - parameter indices: the highlighted values + func drawHighlighted(context: CGContext, indices: [Highlight]) + + /// An opportunity for initializing internal buffers used for rendering with a new size. + /// Since this might do memory allocations, it should only be called if necessary. + func initBuffers() + + func isDrawingValuesAllowed(dataProvider: ChartDataProvider?) -> Bool +} diff --git a/Source/Charts/Renderers/LegendRenderer.swift b/Source/Charts/Renderers/LegendRenderer.swift index 93537cd09b..a32344c3aa 100755 --- a/Source/Charts/Renderers/LegendRenderer.swift +++ b/Source/Charts/Renderers/LegendRenderer.swift @@ -17,16 +17,19 @@ import CoreGraphics #endif @objc(ChartLegendRenderer) -open class LegendRenderer: Renderer +open class LegendRenderer: NSObject, Renderer { + @objc public let viewPortHandler: ViewPortHandler + /// the legend object this renderer renders @objc open var legend: Legend? @objc public init(viewPortHandler: ViewPortHandler, legend: Legend?) { - super.init(viewPortHandler: viewPortHandler) - + self.viewPortHandler = viewPortHandler self.legend = legend + + super.init() } /// Prepares the legend and calculates all needed forms, labels and colors. diff --git a/Source/Charts/Renderers/PieChartRenderer.swift b/Source/Charts/Renderers/PieChartRenderer.swift index 3f5fecb30e..c71959e8e1 100644 --- a/Source/Charts/Renderers/PieChartRenderer.swift +++ b/Source/Charts/Renderers/PieChartRenderer.swift @@ -17,18 +17,23 @@ import CoreGraphics #endif -open class PieChartRenderer: DataRenderer +open class PieChartRenderer: NSObject, DataRenderer { + public let viewPortHandler: ViewPortHandler + public let animator: Animator + @objc open weak var chart: PieChartView? @objc public init(chart: PieChartView, animator: Animator, viewPortHandler: ViewPortHandler) { - super.init(animator: animator, viewPortHandler: viewPortHandler) - + self.viewPortHandler = viewPortHandler + self.animator = animator self.chart = chart + + super.init() } - open override func drawData(context: CGContext) + open func drawData(context: CGContext) { guard let chart = chart else { return } @@ -254,7 +259,7 @@ open class PieChartRenderer: DataRenderer context.restoreGState() } - open override func drawValues(context: CGContext) + open func drawValues(context: CGContext) { guard let chart = chart, @@ -545,12 +550,20 @@ open class PieChartRenderer: DataRenderer } } - open override func drawExtras(context: CGContext) + open func drawExtras(context: CGContext) { drawHole(context: context) drawCenterText(context: context) } - + + open func initBuffers() { } + + open func isDrawingValuesAllowed(dataProvider: ChartDataProvider?) -> Bool + { + guard let data = dataProvider?.data else { return false } + return data.entryCount < Int(CGFloat(dataProvider?.maxVisibleCount ?? 0) * viewPortHandler.scaleX) + } + /// draws the hole in the center of the chart and the transparent circle / hole private func drawHole(context: CGContext) { @@ -656,7 +669,7 @@ open class PieChartRenderer: DataRenderer } } - open override func drawHighlighted(context: CGContext, indices: [Highlight]) + open func drawHighlighted(context: CGContext, indices: [Highlight]) { guard let chart = chart, diff --git a/Source/Charts/Renderers/Renderer.swift b/Source/Charts/Renderers/Renderer.swift index 5c929f28e0..dbdcb8ae3b 100644 --- a/Source/Charts/Renderers/Renderer.swift +++ b/Source/Charts/Renderers/Renderer.swift @@ -13,14 +13,8 @@ import Foundation import CoreGraphics @objc(ChartRenderer) -open class Renderer: NSObject -{ - /// the component that handles the drawing area of the chart and it's offsets - @objc open let viewPortHandler: ViewPortHandler +public protocol Renderer { - @objc public init(viewPortHandler: ViewPortHandler) - { - self.viewPortHandler = viewPortHandler - super.init() - } + /// the component that handles the drawing area of the chart and it's offsets + var viewPortHandler: ViewPortHandler { get } } diff --git a/Source/Charts/Renderers/Scatter/ChevronDownShapeRenderer.swift b/Source/Charts/Renderers/Scatter/ChevronDownShapeRenderer.swift index 152c44ab80..1dab1cc46b 100644 --- a/Source/Charts/Renderers/Scatter/ChevronDownShapeRenderer.swift +++ b/Source/Charts/Renderers/Scatter/ChevronDownShapeRenderer.swift @@ -11,7 +11,7 @@ import Foundation import CoreGraphics -open class ChevronDownShapeRenderer : NSObject, IShapeRenderer +open class ChevronDownShapeRenderer : NSObject, ShapeRenderer { open func renderShape( context: CGContext, diff --git a/Source/Charts/Renderers/Scatter/ChevronUpShapeRenderer.swift b/Source/Charts/Renderers/Scatter/ChevronUpShapeRenderer.swift index 8b416684d8..0d077707f7 100644 --- a/Source/Charts/Renderers/Scatter/ChevronUpShapeRenderer.swift +++ b/Source/Charts/Renderers/Scatter/ChevronUpShapeRenderer.swift @@ -11,7 +11,7 @@ import Foundation import CoreGraphics -open class ChevronUpShapeRenderer : NSObject, IShapeRenderer +open class ChevronUpShapeRenderer : NSObject, ShapeRenderer { open func renderShape( context: CGContext, diff --git a/Source/Charts/Renderers/Scatter/CircleShapeRenderer.swift b/Source/Charts/Renderers/Scatter/CircleShapeRenderer.swift index 27dd6a8dea..fc0c4dfef1 100644 --- a/Source/Charts/Renderers/Scatter/CircleShapeRenderer.swift +++ b/Source/Charts/Renderers/Scatter/CircleShapeRenderer.swift @@ -11,7 +11,7 @@ import Foundation import CoreGraphics -open class CircleShapeRenderer : NSObject, IShapeRenderer +open class CircleShapeRenderer : NSObject, ShapeRenderer { open func renderShape( context: CGContext, diff --git a/Source/Charts/Renderers/Scatter/CrossShapeRenderer.swift b/Source/Charts/Renderers/Scatter/CrossShapeRenderer.swift index c4f5c5f059..7961da25aa 100644 --- a/Source/Charts/Renderers/Scatter/CrossShapeRenderer.swift +++ b/Source/Charts/Renderers/Scatter/CrossShapeRenderer.swift @@ -11,7 +11,7 @@ import Foundation import CoreGraphics -open class CrossShapeRenderer : NSObject, IShapeRenderer +open class CrossShapeRenderer : NSObject, ShapeRenderer { open func renderShape( context: CGContext, diff --git a/Source/Charts/Renderers/Scatter/IShapeRenderer.swift b/Source/Charts/Renderers/Scatter/ShapeRenderer.swift similarity index 93% rename from Source/Charts/Renderers/Scatter/IShapeRenderer.swift rename to Source/Charts/Renderers/Scatter/ShapeRenderer.swift index b8fd5e7c4a..9b7be2d0ba 100644 --- a/Source/Charts/Renderers/Scatter/IShapeRenderer.swift +++ b/Source/Charts/Renderers/Scatter/ShapeRenderer.swift @@ -1,5 +1,5 @@ // -// IShapeRenderer.swift +// ShapeRenderer.swift // Charts // // Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda @@ -13,7 +13,7 @@ import Foundation import CoreGraphics @objc -public protocol IShapeRenderer: class +public protocol ShapeRenderer: class { /// Renders the provided ScatterDataSet with a shape. /// diff --git a/Source/Charts/Renderers/Scatter/SquareShapeRenderer.swift b/Source/Charts/Renderers/Scatter/SquareShapeRenderer.swift index 76646c68e2..948c1ff2eb 100644 --- a/Source/Charts/Renderers/Scatter/SquareShapeRenderer.swift +++ b/Source/Charts/Renderers/Scatter/SquareShapeRenderer.swift @@ -11,7 +11,7 @@ import Foundation import CoreGraphics -open class SquareShapeRenderer : NSObject, IShapeRenderer +open class SquareShapeRenderer : NSObject, ShapeRenderer { open func renderShape( context: CGContext, diff --git a/Source/Charts/Renderers/Scatter/TriangleShapeRenderer.swift b/Source/Charts/Renderers/Scatter/TriangleShapeRenderer.swift index c73a8b8d09..1f4bdca0d7 100644 --- a/Source/Charts/Renderers/Scatter/TriangleShapeRenderer.swift +++ b/Source/Charts/Renderers/Scatter/TriangleShapeRenderer.swift @@ -11,7 +11,7 @@ import Foundation import CoreGraphics -open class TriangleShapeRenderer : NSObject, IShapeRenderer +open class TriangleShapeRenderer : NSObject, ShapeRenderer { open func renderShape( context: CGContext, diff --git a/Source/Charts/Renderers/Scatter/XShapeRenderer.swift b/Source/Charts/Renderers/Scatter/XShapeRenderer.swift index 67b8a8a9d5..73e2efdd4b 100644 --- a/Source/Charts/Renderers/Scatter/XShapeRenderer.swift +++ b/Source/Charts/Renderers/Scatter/XShapeRenderer.swift @@ -11,7 +11,7 @@ import Foundation import CoreGraphics -open class XShapeRenderer : NSObject, IShapeRenderer +open class XShapeRenderer : NSObject, ShapeRenderer { open func renderShape( context: CGContext, diff --git a/Source/Charts/Renderers/ScatterChartRenderer.swift b/Source/Charts/Renderers/ScatterChartRenderer.swift index 756a6c81a5..d7b1afa3a5 100644 --- a/Source/Charts/Renderers/ScatterChartRenderer.swift +++ b/Source/Charts/Renderers/ScatterChartRenderer.swift @@ -94,7 +94,7 @@ open class ScatterChartRenderer: LineScatterCandleRadarRenderer } else { - print("There's no IShapeRenderer specified for ScatterDataSet", terminator: "\n") + print("There's no ShapeRenderer specified for ScatterDataSet", terminator: "\n") } } diff --git a/Source/Charts/Renderers/XAxisRenderer.swift b/Source/Charts/Renderers/XAxisRenderer.swift index 534e606dcf..08811d9a05 100644 --- a/Source/Charts/Renderers/XAxisRenderer.swift +++ b/Source/Charts/Renderers/XAxisRenderer.swift @@ -17,14 +17,22 @@ import CoreGraphics #endif @objc(ChartXAxisRenderer) -open class XAxisRenderer: AxisRendererBase +open class XAxisRenderer: NSObject, AxisRenderer { - @objc public init(viewPortHandler: ViewPortHandler, xAxis: XAxis?, transformer: Transformer?) + public let viewPortHandler: ViewPortHandler + public let axis: XAxis + public let transformer: Transformer? + + @objc public init(viewPortHandler: ViewPortHandler, axis: XAxis, transformer: Transformer?) { - super.init(viewPortHandler: viewPortHandler, transformer: transformer, axis: xAxis) + self.viewPortHandler = viewPortHandler + self.axis = axis + self.transformer = transformer + + super.init() } - open override func computeAxis(min: Double, max: Double, inverted: Bool) + open func computeAxis(min: Double, max: Double, inverted: Bool) { var min = min, max = max @@ -53,60 +61,171 @@ open class XAxisRenderer: AxisRendererBase computeAxisValues(min: min, max: max) } - open override func computeAxisValues(min: Double, max: Double) + open func computeAxisValues(min: Double, max: Double) { - super.computeAxisValues(min: min, max: max) + let yMin = min + let yMax = max + + let labelCount = axis.labelCount + let range = abs(yMax - yMin) + + if labelCount == 0 || range <= 0 || range.isInfinite + { + axis.entries = [Double]() + axis.centeredEntries = [Double]() + return + } + + // Find out how much spacing (in y value space) between axis values + let rawInterval = range / Double(labelCount) + var interval = ChartUtils.roundToNextSignificant(number: Double(rawInterval)) + + // If granularity is enabled, then do not allow the interval to go below specified granularity. + // This is used to avoid repeated values when rounding values for display. + if axis.granularityEnabled + { + interval = interval < axis.granularity ? axis.granularity : interval + } + + // Normalize interval + let intervalMagnitude = ChartUtils.roundToNextSignificant(number: pow(10.0, Double(Int(log10(interval))))) + let intervalSigDigit = Int(interval / intervalMagnitude) + if intervalSigDigit > 5 + { + // Use one order of magnitude higher, to avoid intervals like 0.9 or 90 + interval = floor(10.0 * Double(intervalMagnitude)) + } + + var n = axis.centerAxisLabelsEnabled ? 1 : 0 + + // force label count + if axis.isForceLabelsEnabled + { + interval = Double(range) / Double(labelCount - 1) + + // Ensure stops contains at least n elements. + axis.entries.removeAll(keepingCapacity: true) + axis.entries.reserveCapacity(labelCount) + + var v = yMin + + for _ in 0 ..< labelCount + { + axis.entries.append(v) + v += interval + } + + n = labelCount + } + else + { + // no forced count + + var first = interval == 0.0 ? 0.0 : ceil(yMin / interval) * interval + + if axis.centerAxisLabelsEnabled + { + first -= interval + } + + let last = interval == 0.0 ? 0.0 : ChartUtils.nextUp(floor(yMax / interval) * interval) + + if interval != 0.0 && last != first + { + for _ in stride(from: first, through: last, by: interval) + { + n += 1 + } + } + + // Ensure stops contains at least n elements. + axis.entries.removeAll(keepingCapacity: true) + axis.entries.reserveCapacity(labelCount) + + var f = first + var i = 0 + while i < n + { + if f == 0.0 + { + // Fix for IEEE negative zero case (Where value == -0.0, and 0.0 == -0.0) + f = 0.0 + } + + axis.entries.append(Double(f)) + + f += interval + i += 1 + } + } + + // set decimals + if interval < 1 + { + axis.decimals = Int(ceil(-log10(interval))) + } + else + { + axis.decimals = 0 + } + + if axis.centerAxisLabelsEnabled + { + axis.centeredEntries.reserveCapacity(n) + axis.centeredEntries.removeAll() + + let offset: Double = interval / 2.0 + + for i in 0 ..< n + { + axis.centeredEntries.append(axis.entries[i] + offset) + } + } computeSize() } @objc open func computeSize() { - guard let - xAxis = self.axis as? XAxis - else { return } - - let longest = xAxis.getLongestLabel() + let longest = axis.getLongestLabel() - let labelSize = longest.size(withAttributes: [NSAttributedStringKey.font: xAxis.labelFont]) + let labelSize = longest.size(withAttributes: [NSAttributedStringKey.font: axis.labelFont]) let labelWidth = labelSize.width let labelHeight = labelSize.height - let labelRotatedSize = labelSize.rotatedBy(degrees: xAxis.labelRotationAngle) + let labelRotatedSize = labelSize.rotatedBy(degrees: axis.labelRotationAngle) - xAxis.labelWidth = labelWidth - xAxis.labelHeight = labelHeight - xAxis.labelRotatedWidth = labelRotatedSize.width - xAxis.labelRotatedHeight = labelRotatedSize.height + axis.labelWidth = labelWidth + axis.labelHeight = labelHeight + axis.labelRotatedWidth = labelRotatedSize.width + axis.labelRotatedHeight = labelRotatedSize.height } - open override func renderAxisLabels(context: CGContext) + open func renderAxisLabels(context: CGContext) { - guard let xAxis = self.axis as? XAxis else { return } - - if !xAxis.isEnabled || !xAxis.isDrawLabelsEnabled + if !axis.isEnabled || !axis.isDrawLabelsEnabled { return } - let yOffset = xAxis.yOffset + let yOffset = axis.yOffset - if xAxis.labelPosition == .top + if axis.labelPosition == .top { drawLabels(context: context, pos: viewPortHandler.contentTop - yOffset, anchor: CGPoint(x: 0.5, y: 1.0)) } - else if xAxis.labelPosition == .topInside + else if axis.labelPosition == .topInside { - drawLabels(context: context, pos: viewPortHandler.contentTop + yOffset + xAxis.labelRotatedHeight, anchor: CGPoint(x: 0.5, y: 1.0)) + drawLabels(context: context, pos: viewPortHandler.contentTop + yOffset + axis.labelRotatedHeight, anchor: CGPoint(x: 0.5, y: 1.0)) } - else if xAxis.labelPosition == .bottom + else if axis.labelPosition == .bottom { drawLabels(context: context, pos: viewPortHandler.contentBottom + yOffset, anchor: CGPoint(x: 0.5, y: 0.0)) } - else if xAxis.labelPosition == .bottomInside + else if axis.labelPosition == .bottomInside { - drawLabels(context: context, pos: viewPortHandler.contentBottom - yOffset - xAxis.labelRotatedHeight, anchor: CGPoint(x: 0.5, y: 0.0)) + drawLabels(context: context, pos: viewPortHandler.contentBottom - yOffset - axis.labelRotatedHeight, anchor: CGPoint(x: 0.5, y: 0.0)) } else { // BOTH SIDED @@ -117,31 +236,29 @@ open class XAxisRenderer: AxisRendererBase private var _axisLineSegmentsBuffer = [CGPoint](repeating: CGPoint(), count: 2) - open override func renderAxisLine(context: CGContext) - { - guard let xAxis = self.axis as? XAxis else { return } - - if !xAxis.isEnabled || !xAxis.isDrawAxisLineEnabled + open func renderAxisLine(context: CGContext) + { + if !axis.isEnabled || !axis.isDrawAxisLineEnabled { return } context.saveGState() - context.setStrokeColor(xAxis.axisLineColor.cgColor) - context.setLineWidth(xAxis.axisLineWidth) - if xAxis.axisLineDashLengths != nil + context.setStrokeColor(axis.axisLineColor.cgColor) + context.setLineWidth(axis.axisLineWidth) + if axis.axisLineDashLengths != nil { - context.setLineDash(phase: xAxis.axisLineDashPhase, lengths: xAxis.axisLineDashLengths) + context.setLineDash(phase: axis.axisLineDashPhase, lengths: axis.axisLineDashLengths) } else { context.setLineDash(phase: 0.0, lengths: []) } - if xAxis.labelPosition == .top - || xAxis.labelPosition == .topInside - || xAxis.labelPosition == .bothSided + if axis.labelPosition == .top + || axis.labelPosition == .topInside + || axis.labelPosition == .bothSided { _axisLineSegmentsBuffer[0].x = viewPortHandler.contentLeft _axisLineSegmentsBuffer[0].y = viewPortHandler.contentTop @@ -150,9 +267,9 @@ open class XAxisRenderer: AxisRendererBase context.strokeLineSegments(between: _axisLineSegmentsBuffer) } - if xAxis.labelPosition == .bottom - || xAxis.labelPosition == .bottomInside - || xAxis.labelPosition == .bothSided + if axis.labelPosition == .bottom + || axis.labelPosition == .bottomInside + || axis.labelPosition == .bothSided { _axisLineSegmentsBuffer[0].x = viewPortHandler.contentLeft _axisLineSegmentsBuffer[0].y = viewPortHandler.contentBottom @@ -167,10 +284,7 @@ open class XAxisRenderer: AxisRendererBase /// draws the x-labels on the specified y-position @objc open func drawLabels(context: CGContext, pos: CGFloat, anchor: CGPoint) { - guard - let xAxis = self.axis as? XAxis, - let transformer = self.transformer - else { return } + guard let transformer = self.transformer else { return } #if os(OSX) let paraStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle @@ -179,12 +293,12 @@ open class XAxisRenderer: AxisRendererBase #endif paraStyle.alignment = .center - let labelAttrs: [NSAttributedStringKey : Any] = [NSAttributedStringKey.font: xAxis.labelFont, - NSAttributedStringKey.foregroundColor: xAxis.labelTextColor, + let labelAttrs: [NSAttributedStringKey : Any] = [NSAttributedStringKey.font: axis.labelFont, + NSAttributedStringKey.foregroundColor: axis.labelTextColor, NSAttributedStringKey.paragraphStyle: paraStyle] - let labelRotationAngleRadians = xAxis.labelRotationAngle.DEG2RAD + let labelRotationAngleRadians = axis.labelRotationAngle.DEG2RAD - let centeringEnabled = xAxis.isCenterAxisLabelsEnabled + let centeringEnabled = axis.isCenterAxisLabelsEnabled let valueToPixelMatrix = transformer.valueToPixelMatrix @@ -192,18 +306,18 @@ open class XAxisRenderer: AxisRendererBase var labelMaxSize = CGSize() - if xAxis.isWordWrapEnabled + if axis.isWordWrapEnabled { - labelMaxSize.width = xAxis.wordWrapWidthPercent * valueToPixelMatrix.a + labelMaxSize.width = axis.wordWrapWidthPercent * valueToPixelMatrix.a } - let entries = xAxis.entries + let entries = axis.entries for i in stride(from: 0, to: entries.count, by: 1) { if centeringEnabled { - position.x = CGFloat(xAxis.centeredEntries[i]) + position.x = CGFloat(axis.centeredEntries[i]) } else { @@ -215,14 +329,14 @@ open class XAxisRenderer: AxisRendererBase if viewPortHandler.isInBoundsX(position.x) { - let label = xAxis.valueFormatter?.stringForValue(xAxis.entries[i], axis: xAxis) ?? "" + let label = axis.valueFormatter?.stringForValue(axis.entries[i], axis: axis) ?? "" let labelns = label as NSString - if xAxis.isAvoidFirstLastClippingEnabled + if axis.isAvoidFirstLastClippingEnabled { // avoid clipping of the last - if i == xAxis.entryCount - 1 && xAxis.entryCount > 1 + if i == axis.entryCount - 1 && axis.entryCount > 1 { let width = labelns.boundingRect(with: labelMaxSize, options: .usesLineFragmentOrigin, attributes: labelAttrs, context: nil).size.width @@ -271,14 +385,11 @@ open class XAxisRenderer: AxisRendererBase angleRadians: angleRadians) } - open override func renderGridLines(context: CGContext) + open func renderGridLines(context: CGContext) { - guard - let xAxis = self.axis as? XAxis, - let transformer = self.transformer - else { return } + guard let transformer = self.transformer else { return } - if !xAxis.isDrawGridLinesEnabled || !xAxis.isEnabled + if !axis.isDrawGridLinesEnabled || !axis.isEnabled { return } @@ -287,14 +398,14 @@ open class XAxisRenderer: AxisRendererBase defer { context.restoreGState() } context.clip(to: self.gridClippingRect) - context.setShouldAntialias(xAxis.gridAntialiasEnabled) - context.setStrokeColor(xAxis.gridColor.cgColor) - context.setLineWidth(xAxis.gridLineWidth) - context.setLineCap(xAxis.gridLineCap) + context.setShouldAntialias(axis.gridAntialiasEnabled) + context.setStrokeColor(axis.gridColor.cgColor) + context.setLineWidth(axis.gridLineWidth) + context.setLineCap(axis.gridLineCap) - if xAxis.gridLineDashLengths != nil + if axis.gridLineDashLengths != nil { - context.setLineDash(phase: xAxis.gridLineDashPhase, lengths: xAxis.gridLineDashLengths) + context.setLineDash(phase: axis.gridLineDashPhase, lengths: axis.gridLineDashLengths) } else { @@ -305,7 +416,7 @@ open class XAxisRenderer: AxisRendererBase var position = CGPoint(x: 0.0, y: 0.0) - let entries = xAxis.entries + let entries = axis.entries for i in stride(from: 0, to: entries.count, by: 1) { @@ -320,7 +431,7 @@ open class XAxisRenderer: AxisRendererBase @objc open var gridClippingRect: CGRect { var contentRect = viewPortHandler.contentRect - let dx = self.axis?.gridLineWidth ?? 0.0 + let dx = self.axis.gridLineWidth contentRect.origin.x -= dx / 2.0 contentRect.size.width += dx return contentRect @@ -338,14 +449,11 @@ open class XAxisRenderer: AxisRendererBase } } - open override func renderLimitLines(context: CGContext) + open func renderLimitLines(context: CGContext) { - guard - let xAxis = self.axis as? XAxis, - let transformer = self.transformer - else { return } + guard let transformer = self.transformer else { return } - var limitLines = xAxis.limitLines + var limitLines = axis.limitLines if limitLines.count == 0 { diff --git a/Source/Charts/Renderers/XAxisRendererHorizontalBarChart.swift b/Source/Charts/Renderers/XAxisRendererHorizontalBarChart.swift index d2e0c29306..23f2dd75d9 100644 --- a/Source/Charts/Renderers/XAxisRendererHorizontalBarChart.swift +++ b/Source/Charts/Renderers/XAxisRendererHorizontalBarChart.swift @@ -20,9 +20,9 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer { internal weak var chart: BarChartView? - @objc public init(viewPortHandler: ViewPortHandler, xAxis: XAxis?, transformer: Transformer?, chart: BarChartView) + @objc public init(viewPortHandler: ViewPortHandler, axis: XAxis, transformer: Transformer?, chart: BarChartView) { - super.init(viewPortHandler: viewPortHandler, xAxis: xAxis, transformer: transformer) + super.init(viewPortHandler: viewPortHandler, axis: axis, transformer: transformer) self.chart = chart } @@ -58,50 +58,42 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer open override func computeSize() { - guard let - xAxis = self.axis as? XAxis - else { return } - - let longest = xAxis.getLongestLabel() as NSString + let longest = axis.getLongestLabel() as NSString - let labelSize = longest.size(withAttributes: [NSAttributedStringKey.font: xAxis.labelFont]) + let labelSize = longest.size(withAttributes: [NSAttributedStringKey.font: axis.labelFont]) - let labelWidth = floor(labelSize.width + xAxis.xOffset * 3.5) + let labelWidth = floor(labelSize.width + axis.xOffset * 3.5) let labelHeight = labelSize.height - let labelRotatedSize = CGSize(width: labelSize.width, height: labelHeight).rotatedBy(degrees: xAxis.labelRotationAngle) + let labelRotatedSize = CGSize(width: labelSize.width, height: labelHeight).rotatedBy(degrees: axis.labelRotationAngle) - xAxis.labelWidth = labelWidth - xAxis.labelHeight = labelHeight - xAxis.labelRotatedWidth = round(labelRotatedSize.width + xAxis.xOffset * 3.5) - xAxis.labelRotatedHeight = round(labelRotatedSize.height) + axis.labelWidth = labelWidth + axis.labelHeight = labelHeight + axis.labelRotatedWidth = round(labelRotatedSize.width + axis.xOffset * 3.5) + axis.labelRotatedHeight = round(labelRotatedSize.height) } open override func renderAxisLabels(context: CGContext) { - guard - let xAxis = self.axis as? XAxis - else { return } - - if !xAxis.isEnabled || !xAxis.isDrawLabelsEnabled || chart?.data === nil + if !axis.isEnabled || !axis.isDrawLabelsEnabled || chart?.data === nil { return } - let xoffset = xAxis.xOffset + let xoffset = axis.xOffset - if xAxis.labelPosition == .top + if axis.labelPosition == .top { drawLabels(context: context, pos: viewPortHandler.contentRight + xoffset, anchor: CGPoint(x: 0.0, y: 0.5)) } - else if xAxis.labelPosition == .topInside + else if axis.labelPosition == .topInside { drawLabels(context: context, pos: viewPortHandler.contentRight - xoffset, anchor: CGPoint(x: 1.0, y: 0.5)) } - else if xAxis.labelPosition == .bottom + else if axis.labelPosition == .bottom { drawLabels(context: context, pos: viewPortHandler.contentLeft - xoffset, anchor: CGPoint(x: 1.0, y: 0.5)) } - else if xAxis.labelPosition == .bottomInside + else if axis.labelPosition == .bottomInside { drawLabels(context: context, pos: viewPortHandler.contentLeft + xoffset, anchor: CGPoint(x: 0.0, y: 0.5)) } @@ -115,21 +107,18 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer /// draws the x-labels on the specified y-position open override func drawLabels(context: CGContext, pos: CGFloat, anchor: CGPoint) { - guard - let xAxis = self.axis as? XAxis, - let transformer = self.transformer - else { return } + guard let transformer = self.transformer else { return } - let labelFont = xAxis.labelFont - let labelTextColor = xAxis.labelTextColor - let labelRotationAngleRadians = xAxis.labelRotationAngle.DEG2RAD + let labelFont = axis.labelFont + let labelTextColor = axis.labelTextColor + let labelRotationAngleRadians = axis.labelRotationAngle.DEG2RAD - let centeringEnabled = xAxis.isCenterAxisLabelsEnabled + let centeringEnabled = axis.isCenterAxisLabelsEnabled // pre allocate to save performance (dont allocate in loop) var position = CGPoint(x: 0.0, y: 0.0) - for i in stride(from: 0, to: xAxis.entryCount, by: 1) + for i in stride(from: 0, to: axis.entryCount, by: 1) { // only fill x values @@ -137,18 +126,18 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer if centeringEnabled { - position.y = CGFloat(xAxis.centeredEntries[i]) + position.y = CGFloat(axis.centeredEntries[i]) } else { - position.y = CGFloat(xAxis.entries[i]) + position.y = CGFloat(axis.entries[i]) } transformer.pointValueToPixel(&position) if viewPortHandler.isInBoundsY(position.y) { - if let label = xAxis.valueFormatter?.stringForValue(xAxis.entries[i], axis: xAxis) + if let label = axis.valueFormatter?.stringForValue(axis.entries[i], axis: axis) { drawLabel( context: context, @@ -184,7 +173,7 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer open override var gridClippingRect: CGRect { var contentRect = viewPortHandler.contentRect - let dy = self.axis?.gridLineWidth ?? 0.0 + let dy = self.axis.gridLineWidth contentRect.origin.y -= dy / 2.0 contentRect.size.height += dy return contentRect @@ -205,29 +194,27 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer open override func renderAxisLine(context: CGContext) { - guard let xAxis = self.axis as? XAxis else { return } - - if !xAxis.isEnabled || !xAxis.isDrawAxisLineEnabled + if !axis.isEnabled || !axis.isDrawAxisLineEnabled { return } context.saveGState() - context.setStrokeColor(xAxis.axisLineColor.cgColor) - context.setLineWidth(xAxis.axisLineWidth) - if xAxis.axisLineDashLengths != nil + context.setStrokeColor(axis.axisLineColor.cgColor) + context.setLineWidth(axis.axisLineWidth) + if axis.axisLineDashLengths != nil { - context.setLineDash(phase: xAxis.axisLineDashPhase, lengths: xAxis.axisLineDashLengths) + context.setLineDash(phase: axis.axisLineDashPhase, lengths: axis.axisLineDashLengths) } else { context.setLineDash(phase: 0.0, lengths: []) } - if xAxis.labelPosition == .top || - xAxis.labelPosition == .topInside || - xAxis.labelPosition == .bothSided + if axis.labelPosition == .top || + axis.labelPosition == .topInside || + axis.labelPosition == .bothSided { context.beginPath() context.move(to: CGPoint(x: viewPortHandler.contentRight, y: viewPortHandler.contentTop)) @@ -235,9 +222,9 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer context.strokePath() } - if xAxis.labelPosition == .bottom || - xAxis.labelPosition == .bottomInside || - xAxis.labelPosition == .bothSided + if axis.labelPosition == .bottom || + axis.labelPosition == .bottomInside || + axis.labelPosition == .bothSided { context.beginPath() context.move(to: CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentTop)) @@ -250,12 +237,9 @@ open class XAxisRendererHorizontalBarChart: XAxisRenderer open override func renderLimitLines(context: CGContext) { - guard - let xAxis = self.axis as? XAxis, - let transformer = self.transformer - else { return } + guard let transformer = self.transformer else { return } - var limitLines = xAxis.limitLines + var limitLines = axis.limitLines if limitLines.count == 0 { diff --git a/Source/Charts/Renderers/XAxisRendererRadarChart.swift b/Source/Charts/Renderers/XAxisRendererRadarChart.swift index ab57149cce..8b92a10b8b 100644 --- a/Source/Charts/Renderers/XAxisRendererRadarChart.swift +++ b/Source/Charts/Renderers/XAxisRendererRadarChart.swift @@ -20,28 +20,25 @@ open class XAxisRendererRadarChart: XAxisRenderer { @objc open weak var chart: RadarChartView? - @objc public init(viewPortHandler: ViewPortHandler, xAxis: XAxis?, chart: RadarChartView) + @objc public init(viewPortHandler: ViewPortHandler, axis: XAxis, chart: RadarChartView) { - super.init(viewPortHandler: viewPortHandler, xAxis: xAxis, transformer: nil) + super.init(viewPortHandler: viewPortHandler, axis: axis, transformer: nil) self.chart = chart } open override func renderAxisLabels(context: CGContext) { - guard let - xAxis = axis as? XAxis, - let chart = chart - else { return } + guard let chart = chart else { return } - if !xAxis.isEnabled || !xAxis.isDrawLabelsEnabled + if !axis.isEnabled || !axis.isDrawLabelsEnabled { return } - let labelFont = xAxis.labelFont - let labelTextColor = xAxis.labelTextColor - let labelRotationAngleRadians = xAxis.labelRotationAngle.RAD2DEG + let labelFont = axis.labelFont + let labelTextColor = axis.labelTextColor + let labelRotationAngleRadians = axis.labelRotationAngle.RAD2DEG let drawLabelAnchor = CGPoint(x: 0.5, y: 0.25) let sliceangle = chart.sliceAngle @@ -54,16 +51,16 @@ open class XAxisRendererRadarChart: XAxisRenderer for i in stride(from: 0, to: chart.data?.maxEntryCountSet?.entryCount ?? 0, by: 1) { - let label = xAxis.valueFormatter?.stringForValue(Double(i), axis: xAxis) ?? "" + let label = axis.valueFormatter?.stringForValue(Double(i), axis: axis) ?? "" let angle = (sliceangle * CGFloat(i) + chart.rotationAngle).truncatingRemainder(dividingBy: 360.0) - let p = ChartUtils.getPosition(center: center, dist: CGFloat(chart.yRange) * factor + xAxis.labelRotatedWidth / 2.0, angle: angle) + let p = ChartUtils.getPosition(center: center, dist: CGFloat(chart.yRange) * factor + axis.labelRotatedWidth / 2.0, angle: angle) drawLabel(context: context, formattedLabel: label, x: p.x, - y: p.y - xAxis.labelRotatedHeight / 2.0, + y: p.y - axis.labelRotatedHeight / 2.0, attributes: [NSAttributedStringKey.font: labelFont, NSAttributedStringKey.foregroundColor: labelTextColor], anchor: drawLabelAnchor, angleRadians: labelRotationAngleRadians) diff --git a/Source/Charts/Renderers/YAxisRenderer.swift b/Source/Charts/Renderers/YAxisRenderer.swift index e5b0802575..8ffbf55965 100644 --- a/Source/Charts/Renderers/YAxisRenderer.swift +++ b/Source/Charts/Renderers/YAxisRenderer.swift @@ -17,28 +17,34 @@ import CoreGraphics #endif @objc(ChartYAxisRenderer) -open class YAxisRenderer: AxisRendererBase +open class YAxisRenderer: NSObject, AxisRenderer { - @objc public init(viewPortHandler: ViewPortHandler, yAxis: YAxis?, transformer: Transformer?) + public let viewPortHandler: ViewPortHandler + public let axis: YAxis + public let transformer: Transformer? + + @objc public init(viewPortHandler: ViewPortHandler, axis: YAxis, transformer: Transformer?) { - super.init(viewPortHandler: viewPortHandler, transformer: transformer, axis: yAxis) + self.viewPortHandler = viewPortHandler + self.axis = axis + self.transformer = transformer + + super.init() } /// draws the y-axis labels to the screen - open override func renderAxisLabels(context: CGContext) + open func renderAxisLabels(context: CGContext) { - guard let yAxis = self.axis as? YAxis else { return } - - if !yAxis.isEnabled || !yAxis.isDrawLabelsEnabled + if !axis.isEnabled || !axis.isDrawLabelsEnabled { return } - let xoffset = yAxis.xOffset - let yoffset = yAxis.labelFont.lineHeight / 2.5 + yAxis.yOffset + let xoffset = axis.xOffset + let yoffset = axis.labelFont.lineHeight / 2.5 + axis.yOffset - let dependency = yAxis.axisDependency - let labelPosition = yAxis.labelPosition + let dependency = axis.axisDependency + let labelPosition = axis.labelPosition var xPos = CGFloat(0.0) @@ -76,33 +82,31 @@ open class YAxisRenderer: AxisRendererBase context: context, fixedPosition: xPos, positions: transformedPositions(), - offset: yoffset - yAxis.labelFont.lineHeight, + offset: yoffset - axis.labelFont.lineHeight, textAlign: textAlign) } - open override func renderAxisLine(context: CGContext) + open func renderAxisLine(context: CGContext) { - guard let yAxis = self.axis as? YAxis else { return } - - if !yAxis.isEnabled || !yAxis.drawAxisLineEnabled + if !axis.isEnabled || !axis.drawAxisLineEnabled { return } context.saveGState() - context.setStrokeColor(yAxis.axisLineColor.cgColor) - context.setLineWidth(yAxis.axisLineWidth) - if yAxis.axisLineDashLengths != nil + context.setStrokeColor(axis.axisLineColor.cgColor) + context.setLineWidth(axis.axisLineWidth) + if axis.axisLineDashLengths != nil { - context.setLineDash(phase: yAxis.axisLineDashPhase, lengths: yAxis.axisLineDashLengths) + context.setLineDash(phase: axis.axisLineDashPhase, lengths: axis.axisLineDashLengths) } else { context.setLineDash(phase: 0.0, lengths: []) } - if yAxis.axisDependency == .left + if axis.axisDependency == .left { context.beginPath() context.move(to: CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentTop)) @@ -128,19 +132,15 @@ open class YAxisRenderer: AxisRendererBase offset: CGFloat, textAlign: NSTextAlignment) { - guard - let yAxis = self.axis as? YAxis - else { return } + let labelFont = axis.labelFont + let labelTextColor = axis.labelTextColor - let labelFont = yAxis.labelFont - let labelTextColor = yAxis.labelTextColor - - let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 - let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) + let from = axis.isDrawBottomYLabelEntryEnabled ? 0 : 1 + let to = axis.isDrawTopYLabelEntryEnabled ? axis.entryCount : (axis.entryCount - 1) for i in stride(from: from, to: to, by: 1) { - let text = yAxis.getFormattedLabel(i) + let text = axis.getFormattedLabel(i) ChartUtils.drawText( context: context, @@ -151,18 +151,14 @@ open class YAxisRenderer: AxisRendererBase } } - open override func renderGridLines(context: CGContext) + open func renderGridLines(context: CGContext) { - guard let - yAxis = self.axis as? YAxis - else { return } - - if !yAxis.isEnabled + if !axis.isEnabled { return } - if yAxis.drawGridLinesEnabled + if axis.drawGridLinesEnabled { let positions = transformedPositions() @@ -170,14 +166,14 @@ open class YAxisRenderer: AxisRendererBase defer { context.restoreGState() } context.clip(to: self.gridClippingRect) - context.setShouldAntialias(yAxis.gridAntialiasEnabled) - context.setStrokeColor(yAxis.gridColor.cgColor) - context.setLineWidth(yAxis.gridLineWidth) - context.setLineCap(yAxis.gridLineCap) + context.setShouldAntialias(axis.gridAntialiasEnabled) + context.setStrokeColor(axis.gridColor.cgColor) + context.setLineWidth(axis.gridLineWidth) + context.setLineCap(axis.gridLineCap) - if yAxis.gridLineDashLengths != nil + if axis.gridLineDashLengths != nil { - context.setLineDash(phase: yAxis.gridLineDashPhase, lengths: yAxis.gridLineDashLengths) + context.setLineDash(phase: axis.gridLineDashPhase, lengths: axis.gridLineDashLengths) } else @@ -192,7 +188,7 @@ open class YAxisRenderer: AxisRendererBase } } - if yAxis.drawZeroLineEnabled + if axis.drawZeroLineEnabled { // draw zero line drawZeroLine(context: context) @@ -202,7 +198,7 @@ open class YAxisRenderer: AxisRendererBase @objc open var gridClippingRect: CGRect { var contentRect = viewPortHandler.contentRect - let dy = self.axis?.gridLineWidth ?? 0.0 + let dy = self.axis.gridLineWidth contentRect.origin.y -= dy / 2.0 contentRect.size.height += dy return contentRect @@ -220,17 +216,14 @@ open class YAxisRenderer: AxisRendererBase @objc open func transformedPositions() -> [CGPoint] { - guard - let yAxis = self.axis as? YAxis, - let transformer = self.transformer - else { return [CGPoint]() } + guard let transformer = self.transformer else { return [] } var positions = [CGPoint]() - positions.reserveCapacity(yAxis.entryCount) + positions.reserveCapacity(axis.entryCount) - let entries = yAxis.entries + let entries = axis.entries - for i in stride(from: 0, to: yAxis.entryCount, by: 1) + for i in stride(from: 0, to: axis.entryCount, by: 1) { positions.append(CGPoint(x: 0.0, y: entries[i])) } @@ -244,27 +237,26 @@ open class YAxisRenderer: AxisRendererBase @objc open func drawZeroLine(context: CGContext) { guard - let yAxis = self.axis as? YAxis, let transformer = self.transformer, - let zeroLineColor = yAxis.zeroLineColor + let zeroLineColor = axis.zeroLineColor else { return } context.saveGState() defer { context.restoreGState() } var clippingRect = viewPortHandler.contentRect - clippingRect.origin.y -= yAxis.zeroLineWidth / 2.0 - clippingRect.size.height += yAxis.zeroLineWidth + clippingRect.origin.y -= axis.zeroLineWidth / 2.0 + clippingRect.size.height += axis.zeroLineWidth context.clip(to: clippingRect) context.setStrokeColor(zeroLineColor.cgColor) - context.setLineWidth(yAxis.zeroLineWidth) + context.setLineWidth(axis.zeroLineWidth) let pos = transformer.pixelForValues(x: 0.0, y: 0.0) - - if yAxis.zeroLineDashLengths != nil + + if axis.zeroLineDashLengths != nil { - context.setLineDash(phase: yAxis.zeroLineDashPhase, lengths: yAxis.zeroLineDashLengths!) + context.setLineDash(phase: axis.zeroLineDashPhase, lengths: axis.zeroLineDashLengths!) } else { @@ -276,14 +268,11 @@ open class YAxisRenderer: AxisRendererBase context.drawPath(using: CGPathDrawingMode.stroke) } - open override func renderLimitLines(context: CGContext) + open func renderLimitLines(context: CGContext) { - guard - let yAxis = self.axis as? YAxis, - let transformer = self.transformer - else { return } + guard let transformer = self.transformer else { return } - var limitLines = yAxis.limitLines + var limitLines = axis.limitLines if limitLines.count == 0 { @@ -347,46 +336,196 @@ open class YAxisRenderer: AxisRendererBase if l.labelPosition == .rightTop { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentRight - xOffset, - y: position.y - yOffset), - align: .right, - attributes: [NSAttributedStringKey.font: l.valueFont, NSAttributedStringKey.foregroundColor: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentRight - xOffset, + y: position.y - yOffset), + align: .right, + attributes: [NSAttributedStringKey.font: l.valueFont, NSAttributedStringKey.foregroundColor: l.valueTextColor]) } else if l.labelPosition == .rightBottom { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentRight - xOffset, - y: position.y + yOffset - labelLineHeight), - align: .right, - attributes: [NSAttributedStringKey.font: l.valueFont, NSAttributedStringKey.foregroundColor: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentRight - xOffset, + y: position.y + yOffset - labelLineHeight), + align: .right, + attributes: [NSAttributedStringKey.font: l.valueFont, NSAttributedStringKey.foregroundColor: l.valueTextColor]) } else if l.labelPosition == .leftTop { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentLeft + xOffset, - y: position.y - yOffset), - align: .left, - attributes: [NSAttributedStringKey.font: l.valueFont, NSAttributedStringKey.foregroundColor: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentLeft + xOffset, + y: position.y - yOffset), + align: .left, + attributes: [NSAttributedStringKey.font: l.valueFont, NSAttributedStringKey.foregroundColor: l.valueTextColor]) } else { ChartUtils.drawText(context: context, - text: label, - point: CGPoint( - x: viewPortHandler.contentLeft + xOffset, - y: position.y + yOffset - labelLineHeight), - align: .left, - attributes: [NSAttributedStringKey.font: l.valueFont, NSAttributedStringKey.foregroundColor: l.valueTextColor]) + text: label, + point: CGPoint( + x: viewPortHandler.contentLeft + xOffset, + y: position.y + yOffset - labelLineHeight), + align: .left, + attributes: [NSAttributedStringKey.font: l.valueFont, NSAttributedStringKey.foregroundColor: l.valueTextColor]) } } } context.restoreGState() } + + @objc open func computeAxis(min: Double, max: Double, inverted: Bool) + { + var min = min, max = max + + if let transformer = self.transformer + { + // calculate the starting and entry point of the y-labels (depending on zoom / contentrect bounds) + if viewPortHandler.contentWidth > 10.0 && !viewPortHandler.isFullyZoomedOutY + { + let p1 = transformer.valueForTouchPoint(CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentTop)) + let p2 = transformer.valueForTouchPoint(CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentBottom)) + + if !inverted + { + min = Double(p2.y) + max = Double(p1.y) + } + else + { + min = Double(p1.y) + max = Double(p2.y) + } + } + } + + computeAxisValues(min: min, max: max) + } + + @objc open func computeAxisValues(min: Double, max: Double) + { + let yMin = min + let yMax = max + + let labelCount = axis.labelCount + let range = abs(yMax - yMin) + + if labelCount == 0 || range <= 0 || range.isInfinite + { + axis.entries = [Double]() + axis.centeredEntries = [Double]() + return + } + + // Find out how much spacing (in y value space) between axis values + let rawInterval = range / Double(labelCount) + var interval = ChartUtils.roundToNextSignificant(number: Double(rawInterval)) + + // If granularity is enabled, then do not allow the interval to go below specified granularity. + // This is used to avoid repeated values when rounding values for display. + if axis.granularityEnabled + { + interval = interval < axis.granularity ? axis.granularity : interval + } + + // Normalize interval + let intervalMagnitude = ChartUtils.roundToNextSignificant(number: pow(10.0, Double(Int(log10(interval))))) + let intervalSigDigit = Int(interval / intervalMagnitude) + if intervalSigDigit > 5 + { + // Use one order of magnitude higher, to avoid intervals like 0.9 or 90 + interval = floor(10.0 * Double(intervalMagnitude)) + } + + var n = axis.centerAxisLabelsEnabled ? 1 : 0 + + // force label count + if axis.isForceLabelsEnabled + { + interval = Double(range) / Double(labelCount - 1) + + // Ensure stops contains at least n elements. + axis.entries.removeAll(keepingCapacity: true) + axis.entries.reserveCapacity(labelCount) + + var v = yMin + + for _ in 0 ..< labelCount + { + axis.entries.append(v) + v += interval + } + + n = labelCount + } + else + { + // no forced count + + var first = interval == 0.0 ? 0.0 : ceil(yMin / interval) * interval + + if axis.centerAxisLabelsEnabled + { + first -= interval + } + + let last = interval == 0.0 ? 0.0 : ChartUtils.nextUp(floor(yMax / interval) * interval) + + if interval != 0.0 && last != first + { + for _ in stride(from: first, through: last, by: interval) + { + n += 1 + } + } + + // Ensure stops contains at least n elements. + axis.entries.removeAll(keepingCapacity: true) + axis.entries.reserveCapacity(labelCount) + + var f = first + var i = 0 + while i < n + { + if f == 0.0 + { + // Fix for IEEE negative zero case (Where value == -0.0, and 0.0 == -0.0) + f = 0.0 + } + + axis.entries.append(Double(f)) + + f += interval + i += 1 + } + } + + // set decimals + if interval < 1 + { + axis.decimals = Int(ceil(-log10(interval))) + } + else + { + axis.decimals = 0 + } + + if axis.centerAxisLabelsEnabled + { + axis.centeredEntries.reserveCapacity(n) + axis.centeredEntries.removeAll() + + let offset: Double = interval / 2.0 + + for i in 0 ..< n + { + axis.centeredEntries.append(axis.entries[i] + offset) + } + } + } } diff --git a/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift b/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift index ba7c51f17f..163a74d146 100644 --- a/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift +++ b/Source/Charts/Renderers/YAxisRendererHorizontalBarChart.swift @@ -18,9 +18,9 @@ import CoreGraphics open class YAxisRendererHorizontalBarChart: YAxisRenderer { - public override init(viewPortHandler: ViewPortHandler, yAxis: YAxis?, transformer: Transformer?) + public override init(viewPortHandler: ViewPortHandler, axis: YAxis, transformer: Transformer?) { - super.init(viewPortHandler: viewPortHandler, yAxis: yAxis, transformer: transformer) + super.init(viewPortHandler: viewPortHandler, axis: axis, transformer: transformer) } /// Computes the axis values. @@ -54,18 +54,16 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer /// draws the y-axis labels to the screen open override func renderAxisLabels(context: CGContext) { - guard let yAxis = axis as? YAxis else { return } - - if !yAxis.isEnabled || !yAxis.isDrawLabelsEnabled + if !axis.isEnabled || !axis.isDrawLabelsEnabled { return } - let lineHeight = yAxis.labelFont.lineHeight + let lineHeight = axis.labelFont.lineHeight let baseYOffset: CGFloat = 2.5 - let dependency = yAxis.axisDependency - let labelPosition = yAxis.labelPosition + let dependency = axis.axisDependency + let labelPosition = axis.labelPosition var yPos: CGFloat = 0.0 @@ -100,32 +98,30 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer context: context, fixedPosition: yPos, positions: transformedPositions(), - offset: yAxis.yOffset) + offset: axis.yOffset) } open override func renderAxisLine(context: CGContext) { - guard let yAxis = axis as? YAxis else { return } - - if !yAxis.isEnabled || !yAxis.drawAxisLineEnabled + if !axis.isEnabled || !axis.drawAxisLineEnabled { return } context.saveGState() - context.setStrokeColor(yAxis.axisLineColor.cgColor) - context.setLineWidth(yAxis.axisLineWidth) - if yAxis.axisLineDashLengths != nil + context.setStrokeColor(axis.axisLineColor.cgColor) + context.setLineWidth(axis.axisLineWidth) + if axis.axisLineDashLengths != nil { - context.setLineDash(phase: yAxis.axisLineDashPhase, lengths: yAxis.axisLineDashLengths) + context.setLineDash(phase: axis.axisLineDashPhase, lengths: axis.axisLineDashLengths) } else { context.setLineDash(phase: 0.0, lengths: []) } - if yAxis.axisDependency == .left + if axis.axisDependency == .left { context.beginPath() context.move(to: CGPoint(x: viewPortHandler.contentLeft, y: viewPortHandler.contentTop)) @@ -149,19 +145,15 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer positions: [CGPoint], offset: CGFloat) { - guard let - yAxis = axis as? YAxis - else { return } - - let labelFont = yAxis.labelFont - let labelTextColor = yAxis.labelTextColor + let labelFont = axis.labelFont + let labelTextColor = axis.labelTextColor - let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 - let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) + let from = axis.isDrawBottomYLabelEntryEnabled ? 0 : 1 + let to = axis.isDrawTopYLabelEntryEnabled ? axis.entryCount : (axis.entryCount - 1) for i in stride(from: from, to: to, by: 1) { - let text = yAxis.getFormattedLabel(i) + let text = axis.getFormattedLabel(i) ChartUtils.drawText( context: context, @@ -175,7 +167,7 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer open override var gridClippingRect: CGRect { var contentRect = viewPortHandler.contentRect - let dx = self.axis?.gridLineWidth ?? 0.0 + let dx = self.axis.gridLineWidth contentRect.origin.x -= dx / 2.0 contentRect.size.width += dx return contentRect @@ -193,17 +185,14 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer open override func transformedPositions() -> [CGPoint] { - guard - let yAxis = self.axis as? YAxis, - let transformer = self.transformer - else { return [CGPoint]() } + guard let transformer = self.transformer else { return [] } var positions = [CGPoint]() - positions.reserveCapacity(yAxis.entryCount) + positions.reserveCapacity(axis.entryCount) - let entries = yAxis.entries + let entries = axis.entries - for i in stride(from: 0, to: yAxis.entryCount, by: 1) + for i in stride(from: 0, to: axis.entryCount, by: 1) { positions.append(CGPoint(x: entries[i], y: 0.0)) } @@ -217,27 +206,26 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer open override func drawZeroLine(context: CGContext) { guard - let yAxis = self.axis as? YAxis, let transformer = self.transformer, - let zeroLineColor = yAxis.zeroLineColor + let zeroLineColor = axis.zeroLineColor else { return } context.saveGState() defer { context.restoreGState() } var clippingRect = viewPortHandler.contentRect - clippingRect.origin.x -= yAxis.zeroLineWidth / 2.0 - clippingRect.size.width += yAxis.zeroLineWidth + clippingRect.origin.x -= axis.zeroLineWidth / 2.0 + clippingRect.size.width += axis.zeroLineWidth context.clip(to: clippingRect) context.setStrokeColor(zeroLineColor.cgColor) - context.setLineWidth(yAxis.zeroLineWidth) + context.setLineWidth(axis.zeroLineWidth) let pos = transformer.pixelForValues(x: 0.0, y: 0.0) - if yAxis.zeroLineDashLengths != nil + if axis.zeroLineDashLengths != nil { - context.setLineDash(phase: yAxis.zeroLineDashPhase, lengths: yAxis.zeroLineDashLengths!) + context.setLineDash(phase: axis.zeroLineDashPhase, lengths: axis.zeroLineDashLengths!) } else { @@ -253,12 +241,9 @@ open class YAxisRendererHorizontalBarChart: YAxisRenderer open override func renderLimitLines(context: CGContext) { - guard - let yAxis = axis as? YAxis, - let transformer = self.transformer - else { return } + guard let transformer = self.transformer else { return } - var limitLines = yAxis.limitLines + var limitLines = axis.limitLines if limitLines.count <= 0 { diff --git a/Source/Charts/Renderers/YAxisRendererRadarChart.swift b/Source/Charts/Renderers/YAxisRendererRadarChart.swift index b23b987556..3ba9787c9e 100644 --- a/Source/Charts/Renderers/YAxisRendererRadarChart.swift +++ b/Source/Charts/Renderers/YAxisRendererRadarChart.swift @@ -20,19 +20,15 @@ open class YAxisRendererRadarChart: YAxisRenderer { private weak var chart: RadarChartView? - @objc public init(viewPortHandler: ViewPortHandler, yAxis: YAxis?, chart: RadarChartView) + @objc public init(viewPortHandler: ViewPortHandler, axis: YAxis, chart: RadarChartView) { - super.init(viewPortHandler: viewPortHandler, yAxis: yAxis, transformer: nil) + super.init(viewPortHandler: viewPortHandler, axis: axis, transformer: nil) self.chart = chart } open override func computeAxisValues(min yMin: Double, max yMax: Double) { - guard let - axis = axis as? YAxis - else { return } - let labelCount = axis.labelCount let range = abs(yMax - yMin) @@ -161,34 +157,31 @@ open class YAxisRendererRadarChart: YAxisRenderer open override func renderAxisLabels(context: CGContext) { - guard let - yAxis = axis as? YAxis, - let chart = chart - else { return } + guard let chart = chart else { return } - if !yAxis.isEnabled || !yAxis.isDrawLabelsEnabled + if !axis.isEnabled || !axis.isDrawLabelsEnabled { return } - let labelFont = yAxis.labelFont - let labelTextColor = yAxis.labelTextColor + let labelFont = axis.labelFont + let labelTextColor = axis.labelTextColor let center = chart.centerOffsets let factor = chart.factor - let labelLineHeight = yAxis.labelFont.lineHeight + let labelLineHeight = axis.labelFont.lineHeight - let from = yAxis.isDrawBottomYLabelEntryEnabled ? 0 : 1 - let to = yAxis.isDrawTopYLabelEntryEnabled ? yAxis.entryCount : (yAxis.entryCount - 1) + let from = axis.isDrawBottomYLabelEntryEnabled ? 0 : 1 + let to = axis.isDrawTopYLabelEntryEnabled ? axis.entryCount : (axis.entryCount - 1) for j in stride(from: from, to: to, by: 1) { - let r = CGFloat(yAxis.entries[j] - yAxis._axisMinimum) * factor + let r = CGFloat(axis.entries[j] - axis._axisMinimum) * factor let p = ChartUtils.getPosition(center: center, dist: r, angle: chart.rotationAngle) - let label = yAxis.getFormattedLabel(j) + let label = axis.getFormattedLabel(j) ChartUtils.drawText( context: context, @@ -205,12 +198,11 @@ open class YAxisRendererRadarChart: YAxisRenderer open override func renderLimitLines(context: CGContext) { guard - let yAxis = axis as? YAxis, let chart = chart, let data = chart.data else { return } - var limitLines = yAxis.limitLines + var limitLines = axis.limitLines if limitLines.count == 0 {