diff --git a/Charts.xcodeproj/project.pbxproj b/Charts.xcodeproj/project.pbxproj index f8a25590db..8f9b5913b1 100644 --- a/Charts.xcodeproj/project.pbxproj +++ b/Charts.xcodeproj/project.pbxproj @@ -27,6 +27,7 @@ 146EE16342C2BADC92E45BF2 /* LineScatterCandleRadarChartDataSetProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 9249AD9AEC8C85772365A128 /* LineScatterCandleRadarChartDataSetProtocol.swift */; }; 17E994DA88777AA1D8CCFC58 /* BarChartDataSet.swift in Sources */ = {isa = PBXBuildFile; fileRef = C31AA65EA27776F8C653C7E8 /* BarChartDataSet.swift */; }; 219192CA6B4895319AB49DCA /* BarLineScatterCandleBubbleRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 5B1C588E9DF6FFD56D7ADF8E /* BarLineScatterCandleBubbleRenderer.swift */; }; + 221CA2922588FCBC00C2DD1E /* Sequence+KeyPath.swift in Sources */ = {isa = PBXBuildFile; fileRef = 221CA2912588FCBC00C2DD1E /* Sequence+KeyPath.swift */; }; 2243BBFD1FF156EC00B49D0B /* EquatableTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 2243BBFB1FF156D000B49D0B /* EquatableTests.swift */; }; 23649EFC635A76022F07FFA6 /* PieChartDataEntry.swift in Sources */ = {isa = PBXBuildFile; fileRef = BD02157CF8CEE1189BF681DA /* PieChartDataEntry.swift */; }; 23FA50B2730D8C7ACA091C4F /* BarChartRenderer.swift in Sources */ = {isa = PBXBuildFile; fileRef = 75F279974FE650E57A061B09 /* BarChartRenderer.swift */; }; @@ -195,6 +196,7 @@ 1F3D55A7E6176D52DC957D27 /* XAxisRendererHorizontalBarChart.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = XAxisRendererHorizontalBarChart.swift; path = Source/Charts/Renderers/XAxisRendererHorizontalBarChart.swift; sourceTree = ""; }; 2194AA554712E6BA2677F114 /* BubbleChartRenderer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = BubbleChartRenderer.swift; path = Source/Charts/Renderers/BubbleChartRenderer.swift; sourceTree = ""; }; 219BC9CEA037F897E92E45D1 /* ScatterChartDataSetProtocol.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = ScatterChartDataSetProtocol.swift; path = Source/Charts/Data/Interfaces/ScatterChartDataSetProtocol.swift; sourceTree = ""; }; + 221CA2912588FCBC00C2DD1E /* Sequence+KeyPath.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; name = "Sequence+KeyPath.swift"; path = "Source/Charts/Utils/Sequence+KeyPath.swift"; sourceTree = ""; }; 2243BBFB1FF156D000B49D0B /* EquatableTests.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; name = EquatableTests.swift; path = Tests/Charts/EquatableTests.swift; sourceTree = ""; }; 23D35CF6F9177D77B6B97AE1 /* XShapeRenderer.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = XShapeRenderer.swift; path = Source/Charts/Renderers/Scatter/XShapeRenderer.swift; sourceTree = ""; }; 2440DB759AB93B4A928A3F6F /* RadarChartView.swift */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = sourcecode.swift; name = RadarChartView.swift; path = Source/Charts/Charts/RadarChartView.swift; sourceTree = ""; }; @@ -647,6 +649,7 @@ C9F3DC252355F791000C3215 /* Platform+Gestures.swift */, C9F3DC242355F791000C3215 /* Platform+Graphics.swift */, C9F3DC282355FA2F000C3215 /* Platform+Touch Handling.swift */, + 221CA2912588FCBC00C2DD1E /* Sequence+KeyPath.swift */, FF475B9593B9898853814340 /* Transformer.swift */, 324C9127B53A8D39C8B49277 /* TransformerHorizontalBarChart.swift */, 72EAEBB7CF73E33565FC2896 /* ViewPortHandler.swift */, @@ -911,6 +914,7 @@ B539114951455C35BADAE3F3 /* PieChartDataSet.swift in Sources */, 0C52C70C6E6EA09BD7426386 /* RadarChartData.swift in Sources */, C2EFB4EC8C97FA9987F1B50D /* RadarChartDataEntry.swift in Sources */, + 221CA2922588FCBC00C2DD1E /* Sequence+KeyPath.swift in Sources */, E3B28EA1E21279DF3889BCE8 /* RadarChartDataSet.swift in Sources */, 9A26C8DB1F87B01700367599 /* DataApproximator+N.swift in Sources */, 2B791E64E7C4523B1A63F72A /* ScatterChartData.swift in Sources */, diff --git a/Source/Charts/Charts/ChartViewBase.swift b/Source/Charts/Charts/ChartViewBase.swift index 9ce56fc16e..f978a93dba 100644 --- a/Source/Charts/Charts/ChartViewBase.swift +++ b/Source/Charts/Charts/ChartViewBase.swift @@ -4,7 +4,7 @@ // // Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda // A port of MPAndroidChart for iOS -// Licensed under Apache License 2.0 +// Licensed under Apache License 3.0 // // https://github.com/danielgindi/Charts // @@ -62,12 +62,9 @@ open class ChartViewBase: NSUIView, ChartDataProvider, AnimatorDelegate // calculate how many digits are needed setupDefaultFormatter(min: data.yMin, max: data.yMax) - for set in data + for set in data where set.valueFormatter is DefaultValueFormatter { - if set.valueFormatter is DefaultValueFormatter - { - set.valueFormatter = defaultValueFormatter - } + set.valueFormatter = defaultValueFormatter } // let the chart know there is new data diff --git a/Source/Charts/Components/AxisBase.swift b/Source/Charts/Components/AxisBase.swift index 2544f90d77..83db26b62c 100644 --- a/Source/Charts/Components/AxisBase.swift +++ b/Source/Charts/Components/AxisBase.swift @@ -133,19 +133,12 @@ open class AxisBase: ComponentBase @objc open func getLongestLabel() -> String { - var longest = "" - - for i in entries.indices - { - let text = getFormattedLabel(i) - - if longest.count < text.count - { - longest = text - } - } - - return longest + let longest = entries.indices + .lazy + .map(getFormattedLabel(_:)) + .max(by: \.count) + + return longest ?? "" } /// - Returns: The formatted label at the specified index. This will either use the auto-formatter or the custom formatter (if one is set). diff --git a/Source/Charts/Data/Implementations/Standard/BarChartData.swift b/Source/Charts/Data/Implementations/Standard/BarChartData.swift index ff7ac7e3cd..0403c76b71 100644 --- a/Source/Charts/Data/Implementations/Standard/BarChartData.swift +++ b/Source/Charts/Data/Implementations/Standard/BarChartData.swift @@ -91,7 +91,6 @@ open class BarChartData: BarLineScatterCandleBubbleChartData { fromX += diff } - } notifyDataChanged() diff --git a/Source/Charts/Data/Implementations/Standard/BarChartDataEntry.swift b/Source/Charts/Data/Implementations/Standard/BarChartDataEntry.swift index 196f1aecf8..86a8fa2645 100644 --- a/Source/Charts/Data/Implementations/Standard/BarChartDataEntry.swift +++ b/Source/Charts/Data/Implementations/Standard/BarChartDataEntry.swift @@ -112,6 +112,8 @@ open class BarChartDataEntry: ChartDataEntry return _positiveSum } + var stackSize: Int { yValues?.count ?? 1} + @objc open func calcPosNegSum() { (_negativeSum, _positiveSum) = _yVals?.reduce(into: (0,0)) { (result, y) in @@ -175,7 +177,7 @@ open class BarChartDataEntry: ChartDataEntry get { return self._yVals } set { - self.y = BarChartDataEntry.calcSum(values: newValue) + self.y = BarChartDataEntry.calcSum(values: newValue ?? []) self._yVals = newValue calcPosNegSum() calcRanges() @@ -205,18 +207,8 @@ open class BarChartDataEntry: ChartDataEntry /// - Parameters: /// - vals: /// - Returns: - private static func calcSum(values: [Double]?) -> Double + private static func calcSum(values: [Double]) -> Double { - guard let values = values - else { return 0.0 } - - var sum = 0.0 - - for f in values - { - sum += f - } - - return sum + values.reduce(into: 0, +=) } } diff --git a/Source/Charts/Data/Implementations/Standard/BarChartDataSet.swift b/Source/Charts/Data/Implementations/Standard/BarChartDataSet.swift index 8e080ae094..aae7ae30ae 100644 --- a/Source/Charts/Data/Implementations/Standard/BarChartDataSet.swift +++ b/Source/Charts/Data/Implementations/Standard/BarChartDataSet.swift @@ -48,18 +48,17 @@ open class BarChartDataSet: BarLineScatterCandleBubbleChartDataSet, BarChartData /// stacks. All values belonging to a stack are calculated separately. private func calcEntryCountIncludingStacks(entries: [BarChartDataEntry]) { - _entryCountStacks = 0 - - entries.forEach { _entryCountStacks += $0.yValues?.count ?? 1 } + _entryCountStacks = entries.lazy + .map(\.stackSize) + .reduce(into: 0, +=) } /// calculates the maximum stacksize that occurs in the Entries array of this DataSet private func calcStackSize(entries: [BarChartDataEntry]) { - for e in entries where (e.yValues?.count ?? 0) > _stackSize - { - _stackSize = e.yValues!.count - } + _stackSize = entries.lazy + .map(\.stackSize) + .max() ?? 1 } open override func calcMinMax(entry e: ChartDataEntry) diff --git a/Source/Charts/Highlight/BarHighlighter.swift b/Source/Charts/Highlight/BarHighlighter.swift index 3191b5d7a6..904302cf14 100644 --- a/Source/Charts/Highlight/BarHighlighter.swift +++ b/Source/Charts/Highlight/BarHighlighter.swift @@ -98,6 +98,7 @@ open class BarHighlighter: ChartHighlighter @objc open func getClosestStackIndex(ranges: [Range]?, value: Double) -> Int { guard let ranges = ranges else { return 0 } + if let stackIndex = ranges.firstIndex(where: { $0.contains(value) }) { return stackIndex } else { diff --git a/Source/Charts/Highlight/RadarHighlighter.swift b/Source/Charts/Highlight/RadarHighlighter.swift index e0e9844b94..e5f087e00f 100644 --- a/Source/Charts/Highlight/RadarHighlighter.swift +++ b/Source/Charts/Highlight/RadarHighlighter.swift @@ -22,20 +22,12 @@ open class RadarHighlighter: PieRadarHighlighter let highlights = getHighlights(forIndex: index) let distanceToCenter = Double(chart.distanceToCenter(x: x, y: y) / chart.factor) - - var closest: Highlight? - var distance = Double.greatestFiniteMagnitude - - for high in highlights - { - let cdistance = abs(high.y - distanceToCenter) - if cdistance < distance - { - closest = high - distance = cdistance - } + + func closestToCenter(lhs: Highlight, rhs: Highlight) -> Bool { + abs(lhs.y - distanceToCenter) < abs(rhs.y - distanceToCenter) } - + + let closest = highlights.min(by: closestToCenter(lhs:rhs:)) return closest } diff --git a/Source/Charts/Renderers/BarChartRenderer.swift b/Source/Charts/Renderers/BarChartRenderer.swift index 9f71e9d626..e04473d234 100644 --- a/Source/Charts/Renderers/BarChartRenderer.swift +++ b/Source/Charts/Renderers/BarChartRenderer.swift @@ -391,12 +391,13 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer // Create and append the corresponding accessibility element to accessibilityOrderedElements if let chart = dataProvider as? BarChartView { - let element = createAccessibleElement(withIndex: j, - container: chart, - dataSet: dataSet, - dataSetIndex: index, - stackSize: stackSize) - { (element) in + let element = createAccessibleElement( + withIndex: j, + container: chart, + dataSet: dataSet, + dataSetIndex: index, + stackSize: stackSize + ) { (element) in element.accessibilityFrame = barRect } @@ -536,8 +537,9 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer // if we have stacks var bufferIndex = 0 - - for index in 0 ..< Int(ceil(Double(dataSet.entryCount) * animator.phaseX)) + let lastIndex = ceil(Double(dataSet.entryCount) * animator.phaseX) + + for index in 0 ..< Int(lastIndex) { guard let e = dataSet.entryForIndex(index) as? BarChartDataEntry else { continue } @@ -548,7 +550,7 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer let x = rect.origin.x + rect.size.width / 2.0 // we still draw stacked bars, but there is one non-stacked in between - if let vals = vals + if let values = vals { // draw stack values var transformed = [CGPoint]() @@ -556,11 +558,10 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer var posY = 0.0 var negY = -e.negativeSum - for k in vals.indices + for value in values { - let value = vals[k] - var y: Double - + let y: Double + if value == 0.0 && (posY == 0.0 || negY == 0.0) { // Take care of the situation of a 0.0 value, which overlaps a non-zero bar @@ -582,9 +583,9 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer trans.pointValuesToPixel(&transformed) - for (val, transformed) in zip(vals, transformed) + for (value, transformed) in zip(values, transformed) { - let drawBelow = (val == 0.0 && negY == 0.0 && posY > 0.0) || val < 0.0 + let drawBelow = (value == 0.0 && negY == 0.0 && posY > 0.0) || value < 0.0 let y = transformed.y + (drawBelow ? negOffset : posOffset) guard viewPortHandler.isInBoundsRight(x) else { break } @@ -597,7 +598,7 @@ open class BarChartRenderer: BarLineScatterCandleBubbleRenderer drawValue( context: context, value: formatter.stringForValue( - val, + value, entry: e, dataSetIndex: dataSetIndex, viewPortHandler: viewPortHandler), diff --git a/Source/Charts/Renderers/BubbleChartRenderer.swift b/Source/Charts/Renderers/BubbleChartRenderer.swift index ed1cf46147..fa96a6f91e 100644 --- a/Source/Charts/Renderers/BubbleChartRenderer.swift +++ b/Source/Charts/Renderers/BubbleChartRenderer.swift @@ -45,7 +45,8 @@ open class BubbleChartRenderer: BarLineScatterCandleBubbleRenderer accessibleChartElements.append(element) } - for case let (i, set) as (Int, BubbleChartDataSetProtocol) in bubbleData.enumerated() where set.isVisible + let sets = bubbleData.dataSets as! [BubbleChartDataSet] + for case let (i, set) in zip(sets.indices, sets) where set.isVisible { drawDataSet(context: context, dataSet: set, dataSetIndex: i) } diff --git a/Source/Charts/Renderers/CombinedChartRenderer.swift b/Source/Charts/Renderers/CombinedChartRenderer.swift index c215cd2190..de6121df63 100644 --- a/Source/Charts/Renderers/CombinedChartRenderer.swift +++ b/Source/Charts/Renderers/CombinedChartRenderer.swift @@ -59,35 +59,30 @@ open class CombinedChartRenderer: NSObject, DataRenderer { _renderers.append(BarChartRenderer(dataProvider: chart, animator: animator, viewPortHandler: viewPortHandler)) } - break - + case .line: if chart.lineData !== nil { _renderers.append(LineChartRenderer(dataProvider: chart, animator: animator, viewPortHandler: viewPortHandler)) } - break - + case .candle: if chart.candleData !== nil { _renderers.append(CandleStickChartRenderer(dataProvider: chart, animator: animator, viewPortHandler: viewPortHandler)) } - break - + case .scatter: if chart.scatterData !== nil { _renderers.append(ScatterChartRenderer(dataProvider: chart, animator: animator, viewPortHandler: viewPortHandler)) } - break - + case .bubble: if chart.bubbleData !== nil { _renderers.append(BubbleChartRenderer(dataProvider: chart, animator: animator, viewPortHandler: viewPortHandler)) } - break } } @@ -190,10 +185,7 @@ open class CombinedChartRenderer: NSObject, DataRenderer /// e.g. if you provide [DrawOrder.Bar, DrawOrder.Line], the bars will be drawn behind the lines. open var drawOrder: [CombinedChartView.DrawOrder] { - get - { - return _drawOrder - } + get { _drawOrder } set { if !newValue.isEmpty diff --git a/Source/Charts/Renderers/LineChartRenderer.swift b/Source/Charts/Renderers/LineChartRenderer.swift index 459e2e8ea6..ec622967ee 100644 --- a/Source/Charts/Renderers/LineChartRenderer.swift +++ b/Source/Charts/Renderers/LineChartRenderer.swift @@ -32,18 +32,14 @@ open class LineChartRenderer: LineRadarRenderer open override func drawData(context: CGContext) { guard let lineData = dataProvider?.lineData else { return } - - for i in lineData.indices - { - guard let set = lineData[i] as? LineChartDataSetProtocol else - { - fatalError("Datasets for LineChartRenderer must conform to LineChartDataSetProtocol") - } - guard set.isVisible else { continue } + let sets = lineData.dataSets as? [LineChartDataSet] + assert(sets != nil, "Datasets for LineChartRenderer must conform to ILineChartDataSet") - drawDataSet(context: context, dataSet: set) - } + let drawDataSet = { self.drawDataSet(context: context, dataSet: $0) } + sets!.lazy + .filter(\.isVisible) + .forEach(drawDataSet) } @objc open func drawDataSet(context: CGContext, dataSet: LineChartDataSetProtocol) @@ -269,7 +265,7 @@ open class LineChartRenderer: LineRadarRenderer { guard let dataProvider = dataProvider - else { return } + else { return } if bounds.range <= 0 { @@ -373,7 +369,7 @@ open class LineChartRenderer: LineRadarRenderer { break } - + // Determine the start and end coordinates of the line, and make sure they differ. guard let firstCoordinate = _lineSegments.first, @@ -381,9 +377,9 @@ open class LineChartRenderer: LineRadarRenderer firstCoordinate != lastCoordinate else { continue } // make sure the lines don't do shitty things outside bounds - if !viewPortHandler.isInBoundsLeft(lastCoordinate.x) || - !viewPortHandler.isInBoundsTop(max(firstCoordinate.y, lastCoordinate.y)) || - !viewPortHandler.isInBoundsBottom(min(firstCoordinate.y, lastCoordinate.y)) + if !viewPortHandler.isInBoundsLeft(lastCoordinate.x) || + !viewPortHandler.isInBoundsTop(max(firstCoordinate.y, lastCoordinate.y)) || + !viewPortHandler.isInBoundsBottom(min(firstCoordinate.y, lastCoordinate.y)) { continue } @@ -523,7 +519,7 @@ open class LineChartRenderer: LineRadarRenderer guard let dataProvider = dataProvider, let lineData = dataProvider.lineData - else { return } + else { return } if isDrawingValuesAllowed(dataProvider: dataProvider) { @@ -534,9 +530,9 @@ open class LineChartRenderer: LineRadarRenderer for i in lineData.indices { guard let - dataSet = lineData[i] as? LineChartDataSetProtocol, - shouldDrawValues(forDataSet: dataSet) - else { continue } + dataSet = lineData[i] as? LineChartDataSetProtocol, + shouldDrawValues(forDataSet: dataSet) + else { continue } let valueFont = dataSet.valueFont @@ -595,7 +591,7 @@ open class LineChartRenderer: LineRadarRenderer { context.drawImage(icon, atCenter: CGPoint(x: pt.x + iconsOffset.x, - y: pt.y + iconsOffset.y), + y: pt.y + iconsOffset.y), size: icon.size) } } @@ -613,7 +609,7 @@ open class LineChartRenderer: LineRadarRenderer guard let dataProvider = dataProvider, let lineData = dataProvider.lineData - else { return } + else { return } let phaseY = animator.phaseY @@ -756,7 +752,7 @@ open class LineChartRenderer: LineRadarRenderer guard let dataProvider = dataProvider, let lineData = dataProvider.lineData - else { return } + else { return } let chartXMax = dataProvider.chartXMax @@ -765,8 +761,8 @@ open class LineChartRenderer: LineRadarRenderer for high in indices { guard let set = lineData[high.dataSetIndex] as? LineChartDataSetProtocol, - set.isHighlightEnabled - else { continue } + set.isHighlightEnabled + else { continue } guard let e = set.entryForXValue(high.x, closestToY: high.y) else { continue } @@ -835,7 +831,7 @@ open class LineChartRenderer: LineRadarRenderer return } components += [r, g, b, a] - } + } let gradientLocations: [CGFloat] = gradientPositions.reversed() .map { (position) in let location = CGPoint(x: boundingBox.minX, y: position) @@ -843,14 +839,14 @@ open class LineChartRenderer: LineRadarRenderer let normalizedLocation = (location.y - boundingBox.minY) / (boundingBox.maxY - boundingBox.minY) return normalizedLocation.clamped(to: 0...1) - } + } let baseColorSpace = CGColorSpaceCreateDeviceRGB() guard let gradient = CGGradient( - colorSpace: baseColorSpace, - colorComponents: gradientColorComponents, - locations: gradientLocations, - count: gradientLocations.count) else { + colorSpace: baseColorSpace, + colorComponents: gradientColorComponents, + locations: gradientLocations, + count: gradientLocations.count) else { return } @@ -880,10 +876,10 @@ open class LineChartRenderer: LineRadarRenderer /// i.e. in case of a stacked chart, this returns each stack, not the combined bar. /// Note that it is marked internal to support subclass modification in the HorizontalBarChart. private func createAccessibleElement(withIndex idx: Int, - container: LineChartView, - dataSet: LineChartDataSetProtocol, - dataSetIndex: Int, - modifier: (NSUIAccessibilityElement) -> ()) -> NSUIAccessibilityElement + container: LineChartView, + dataSet: LineChartDataSetProtocol, + dataSetIndex: Int, + modifier: (NSUIAccessibilityElement) -> ()) -> NSUIAccessibilityElement { let element = NSUIAccessibilityElement(accessibilityContainer: container) let xAxis = container.xAxis @@ -897,9 +893,9 @@ open class LineChartRenderer: LineRadarRenderer let label = xAxis.valueFormatter?.stringForValue(e.x, axis: xAxis) ?? "\(e.x)" let elementValueText = dataSet.valueFormatter.stringForValue(e.y, - entry: e, - dataSetIndex: dataSetIndex, - viewPortHandler: viewPortHandler) + entry: e, + dataSetIndex: dataSetIndex, + viewPortHandler: viewPortHandler) let dataSetCount = dataProvider.lineData?.dataSetCount ?? -1 let doesContainMultipleDataSets = dataSetCount > 1 diff --git a/Source/Charts/Renderers/ScatterChartRenderer.swift b/Source/Charts/Renderers/ScatterChartRenderer.swift index d80e572964..9fb1f560c7 100644 --- a/Source/Charts/Renderers/ScatterChartRenderer.swift +++ b/Source/Charts/Renderers/ScatterChartRenderer.swift @@ -41,17 +41,13 @@ open class ScatterChartRenderer: LineScatterCandleRadarRenderer // TODO: Due to the potential complexity of data presented in Scatter charts, a more usable way // for VO accessibility would be to use axis based traversal rather than by dataset. // Hence, accessibleChartElements is not populated below. (Individual renderers guard against dataSource being their respective views) - for i in scatterData.indices - { - guard let set = scatterData[i] as? ScatterChartDataSetProtocol else - { - fatalError("Datasets for ScatterChartRenderer must conform to ScatterChartDataSetProtocol") - } - - guard set.isVisible else { continue } - - drawDataSet(context: context, dataSet: set) - } + let sets = scatterData.dataSets as? [ScatterChartDataSet] + assert(sets != nil, "Datasets for ScatterChartRenderer must conform to IScatterChartDataSet") + + let drawDataSet = { self.drawDataSet(context: context, dataSet: $0) } + sets!.lazy + .filter(\.isVisible) + .forEach(drawDataSet) } private var _lineSegments = [CGPoint](repeating: CGPoint(), count: 2) diff --git a/Source/Charts/Utils/Platform+Accessibility.swift b/Source/Charts/Utils/Platform+Accessibility.swift index d936ae2e77..d2bced7b26 100644 --- a/Source/Charts/Utils/Platform+Accessibility.swift +++ b/Source/Charts/Utils/Platform+Accessibility.swift @@ -16,12 +16,12 @@ import UIKit internal func accessibilityPostLayoutChangedNotification(withElement element: Any? = nil) { - UIAccessibility.post(notification: UIAccessibility.Notification.layoutChanged, argument: element) + UIAccessibility.post(notification: .layoutChanged, argument: element) } internal func accessibilityPostScreenChangedNotification(withElement element: Any? = nil) { - UIAccessibility.post(notification: UIAccessibility.Notification.screenChanged, argument: element) + UIAccessibility.post(notification: .screenChanged, argument: element) } /// A simple abstraction over UIAccessibilityElement and NSAccessibilityElement. @@ -33,7 +33,7 @@ open class NSUIAccessibilityElement: UIAccessibilityElement { didSet { - accessibilityTraits = isHeader ? UIAccessibilityTraits.header : UIAccessibilityTraits.none + accessibilityTraits = isHeader ? .header : .none } } @@ -41,7 +41,7 @@ open class NSUIAccessibilityElement: UIAccessibilityElement { didSet { - accessibilityTraits = isSelected ? UIAccessibilityTraits.selected : UIAccessibilityTraits.none + accessibilityTraits = isSelected ? .selected : .none } } diff --git a/Source/Charts/Utils/Sequence+KeyPath.swift b/Source/Charts/Utils/Sequence+KeyPath.swift new file mode 100644 index 0000000000..fd3679893c --- /dev/null +++ b/Source/Charts/Utils/Sequence+KeyPath.swift @@ -0,0 +1,19 @@ +// +// Sequence+KeyPath.swift +// Charts +// +// Created by Jacob Christie on 2020-12-15. +// + +extension Sequence { + func max( + by keyPath: KeyPath, + areInIncreasingOrder: (T, T) -> Bool + ) -> Element? { + self.max { areInIncreasingOrder($0[keyPath: keyPath], $1[keyPath: keyPath]) } + } + + func max(by keyPath: KeyPath) -> Element? { + max(by: keyPath, areInIncreasingOrder: <) + } +}