From 2a1ecb4e6f175f91e91d77d039be342138fe0e3c Mon Sep 17 00:00:00 2001 From: Jacob Christie Date: Sat, 26 Jan 2019 14:21:10 -0400 Subject: [PATCH] BarLineScatterCandleBubbleRenderer.XBounds conformance to RangeExpression and Sequence Sequence conformance simplifies for-in loops Looking forward to when data types conforming to Collection, RangeExpression conformance by XBounds allows for slicing of the collections further simplifying algorithms on data/datasets. --- .../BarLineScatterCandleBubbleRenderer.swift | 38 ++++++++++++++++++- .../Renderers/BubbleChartRenderer.swift | 4 +- .../Renderers/CandleStickChartRenderer.swift | 4 +- .../Charts/Renderers/LineChartRenderer.swift | 10 ++--- .../Renderers/ScatterChartRenderer.swift | 2 +- 5 files changed, 46 insertions(+), 12 deletions(-) diff --git a/Source/Charts/Renderers/BarLineScatterCandleBubbleRenderer.swift b/Source/Charts/Renderers/BarLineScatterCandleBubbleRenderer.swift index 39acdb00ed..9ae8651a22 100644 --- a/Source/Charts/Renderers/BarLineScatterCandleBubbleRenderer.swift +++ b/Source/Charts/Renderers/BarLineScatterCandleBubbleRenderer.swift @@ -78,8 +78,8 @@ open class BarLineScatterCandleBubbleRenderer: DataRenderer let low = chart.lowestVisibleX let high = chart.highestVisibleX - let entryFrom = dataSet.entryForXValue(low, closestToY: Double.nan, rounding: ChartDataSetRounding.down) - let entryTo = dataSet.entryForXValue(high, closestToY: Double.nan, rounding: ChartDataSetRounding.up) + let entryFrom = dataSet.entryForXValue(low, closestToY: .nan, rounding: .down) + let entryTo = dataSet.entryForXValue(high, closestToY: .nan, rounding: .up) self.min = entryFrom == nil ? 0 : dataSet.entryIndex(entry: entryFrom!) self.max = entryTo == nil ? 0 : dataSet.entryIndex(entry: entryTo!) @@ -87,3 +87,37 @@ open class BarLineScatterCandleBubbleRenderer: DataRenderer } } } + +extension BarLineScatterCandleBubbleRenderer.XBounds: RangeExpression { + public func relative(to collection: C) -> Swift.Range + where C : Collection, Bound == C.Index + { + return Swift.Range(min...min + range) + } + + public func contains(_ element: Int) -> Bool { + return (min...min + range).contains(element) + } +} + +extension BarLineScatterCandleBubbleRenderer.XBounds: Sequence { + public struct Iterator: IteratorProtocol { + private let bounds: BarLineScatterCandleBubbleRenderer.XBounds + private var value: Int + + fileprivate init(bounds: BarLineScatterCandleBubbleRenderer.XBounds) { + self.bounds = bounds + self.value = bounds.min + } + + public mutating func next() -> Int? { + guard value < bounds.max else { return nil } + value += 1 + return value + } + } + + public func makeIterator() -> Iterator { + return Iterator(bounds: self) + } +} diff --git a/Source/Charts/Renderers/BubbleChartRenderer.swift b/Source/Charts/Renderers/BubbleChartRenderer.swift index 5309092cad..865ce46d93 100644 --- a/Source/Charts/Renderers/BubbleChartRenderer.swift +++ b/Source/Charts/Renderers/BubbleChartRenderer.swift @@ -105,7 +105,7 @@ open class BubbleChartRenderer: BarLineScatterCandleBubbleRenderer let maxBubbleHeight: CGFloat = abs(viewPortHandler.contentBottom - viewPortHandler.contentTop) let referenceSize: CGFloat = min(maxBubbleHeight, maxBubbleWidth) - for j in stride(from: _xBounds.min, through: _xBounds.range + _xBounds.min, by: 1) + for j in _xBounds { guard let entry = dataSet.entryForIndex(j) as? BubbleChartDataEntry else { continue } @@ -185,7 +185,7 @@ open class BubbleChartRenderer: BarLineScatterCandleBubbleRenderer let iconsOffset = dataSet.iconsOffset - for j in _xBounds.min..._xBounds.range + _xBounds.min + for j in _xBounds { guard let e = dataSet.entryForIndex(j) as? BubbleChartDataEntry else { break } diff --git a/Source/Charts/Renderers/CandleStickChartRenderer.swift b/Source/Charts/Renderers/CandleStickChartRenderer.swift index 6da78b2b20..bf813adfd5 100644 --- a/Source/Charts/Renderers/CandleStickChartRenderer.swift +++ b/Source/Charts/Renderers/CandleStickChartRenderer.swift @@ -77,7 +77,7 @@ open class CandleStickChartRenderer: LineScatterCandleRadarRenderer context.setLineWidth(dataSet.shadowWidth) - for j in stride(from: _xBounds.min, through: _xBounds.range + _xBounds.min, by: 1) + for j in _xBounds { // get the entry guard let e = dataSet.entryForIndex(j) as? CandleChartDataEntry else { continue } @@ -313,7 +313,7 @@ open class CandleStickChartRenderer: LineScatterCandleRadarRenderer let lineHeight = valueFont.lineHeight let yOffset: CGFloat = lineHeight + 5.0 - for j in stride(from: _xBounds.min, through: _xBounds.range + _xBounds.min, by: 1) + for j in _xBounds { guard let e = dataSet.entryForIndex(j) as? CandleChartDataEntry else { break } diff --git a/Source/Charts/Renderers/LineChartRenderer.swift b/Source/Charts/Renderers/LineChartRenderer.swift index 47c6ea73b9..537b2c8db8 100644 --- a/Source/Charts/Renderers/LineChartRenderer.swift +++ b/Source/Charts/Renderers/LineChartRenderer.swift @@ -214,7 +214,7 @@ open class LineChartRenderer: LineRadarRenderer // let the spline start cubicPath.move(to: CGPoint(x: CGFloat(cur.x), y: CGFloat(cur.y * phaseY)), transform: valueToPixelMatrix) - for j in stride(from: (_xBounds.min + 1), through: _xBounds.range + _xBounds.min, by: 1) + for j in _xBounds.dropFirst() { prev = cur cur = dataSet.entryForIndex(j) @@ -325,7 +325,7 @@ open class LineChartRenderer: LineRadarRenderer _lineSegments = [CGPoint](repeating: CGPoint(), count: pointsPerEntryPair) } - for j in stride(from: _xBounds.min, through: _xBounds.range + _xBounds.min, by: 1) + for j in _xBounds { var e: ChartDataEntry! = dataSet.entryForIndex(j) @@ -391,7 +391,7 @@ open class LineChartRenderer: LineRadarRenderer context.beginPath() var firstPoint = true - for x in stride(from: _xBounds.min, through: _xBounds.range + _xBounds.min, by: 1) + for x in _xBounds { e1 = dataSet.entryForIndex(x == 0 ? 0 : (x - 1)) e2 = dataSet.entryForIndex(x) @@ -544,7 +544,7 @@ open class LineChartRenderer: LineRadarRenderer _xBounds.set(chart: dataProvider, dataSet: dataSet, animator: animator) - for j in stride(from: _xBounds.min, through: min(_xBounds.min + _xBounds.range, _xBounds.max), by: 1) + for j in _xBounds { guard let e = dataSet.entryForIndex(j) else { break } @@ -649,7 +649,7 @@ open class LineChartRenderer: LineRadarRenderer (dataSet.circleHoleColor == nil || dataSet.circleHoleColor == NSUIColor.clear) - for j in stride(from: _xBounds.min, through: _xBounds.range + _xBounds.min, by: 1) + for j in _xBounds { guard let e = dataSet.entryForIndex(j) else { break } diff --git a/Source/Charts/Renderers/ScatterChartRenderer.swift b/Source/Charts/Renderers/ScatterChartRenderer.swift index f0669cf553..2f5f45da7f 100644 --- a/Source/Charts/Renderers/ScatterChartRenderer.swift +++ b/Source/Charts/Renderers/ScatterChartRenderer.swift @@ -151,7 +151,7 @@ open class ScatterChartRenderer: LineScatterCandleRadarRenderer _xBounds.set(chart: dataProvider, dataSet: dataSet, animator: animator) - for j in stride(from: _xBounds.min, through: _xBounds.range + _xBounds.min, by: 1) + for j in _xBounds { guard let e = dataSet.entryForIndex(j) else { break }