diff --git a/ChartsDemo-OSX/ChartsDemo-OSX/Demos/BarDemoViewController.swift b/ChartsDemo-OSX/ChartsDemo-OSX/Demos/BarDemoViewController.swift index 88d3b91087..10e9101426 100644 --- a/ChartsDemo-OSX/ChartsDemo-OSX/Demos/BarDemoViewController.swift +++ b/ChartsDemo-OSX/ChartsDemo-OSX/Demos/BarDemoViewController.swift @@ -31,11 +31,11 @@ open class BarDemoViewController: NSViewController let data = BarChartData() let ds1 = BarChartDataSet(values: yse1, label: "Hello") ds1.colors = [NSUIColor.red] - data.addDataSet(ds1) + data.append(ds1) let ds2 = BarChartDataSet(values: yse2, label: "World") ds2.colors = [NSUIColor.blue] - data.addDataSet(ds2) + data.append(ds2) let barWidth = 0.4 let barSpace = 0.05 diff --git a/ChartsDemo-OSX/ChartsDemo-OSX/Demos/LineDemoViewController.swift b/ChartsDemo-OSX/ChartsDemo-OSX/Demos/LineDemoViewController.swift index ea78112cc6..91384c9a19 100644 --- a/ChartsDemo-OSX/ChartsDemo-OSX/Demos/LineDemoViewController.swift +++ b/ChartsDemo-OSX/ChartsDemo-OSX/Demos/LineDemoViewController.swift @@ -30,11 +30,11 @@ open class LineDemoViewController: NSViewController let data = LineChartData() let ds1 = LineChartDataSet(values: yse1, label: "Hello") ds1.colors = [NSUIColor.red] - data.addDataSet(ds1) + data.append(ds1) let ds2 = LineChartDataSet(values: yse2, label: "World") ds2.colors = [NSUIColor.blue] - data.addDataSet(ds2) + data.append(ds2) self.lineChartView.data = data self.lineChartView.gridBackgroundColor = NSUIColor.white diff --git a/ChartsDemo-OSX/ChartsDemo-OSX/Demos/PieDemoViewController.swift b/ChartsDemo-OSX/ChartsDemo-OSX/Demos/PieDemoViewController.swift index 5ace6f32da..de35306ea0 100644 --- a/ChartsDemo-OSX/ChartsDemo-OSX/Demos/PieDemoViewController.swift +++ b/ChartsDemo-OSX/ChartsDemo-OSX/Demos/PieDemoViewController.swift @@ -30,7 +30,7 @@ open class PieDemoViewController: NSViewController ds1.colors = ChartColorTemplates.vordiplom() - data.addDataSet(ds1) + data.append(ds1) let paragraphStyle: NSMutableParagraphStyle = NSParagraphStyle.default.mutableCopy() as! NSMutableParagraphStyle paragraphStyle.lineBreakMode = .byTruncatingTail diff --git a/ChartsDemo-OSX/ChartsDemo-OSX/Demos/RadarDemoViewController.swift b/ChartsDemo-OSX/ChartsDemo-OSX/Demos/RadarDemoViewController.swift index 8f60f97629..e4a83c8fb9 100644 --- a/ChartsDemo-OSX/ChartsDemo-OSX/Demos/RadarDemoViewController.swift +++ b/ChartsDemo-OSX/ChartsDemo-OSX/Demos/RadarDemoViewController.swift @@ -30,11 +30,11 @@ open class RadarDemoViewController: NSViewController let data = RadarChartData() let ds1 = RadarChartDataSet(values: yse1, label: "Hello") ds1.colors = [NSUIColor.red] - data.addDataSet(ds1) + data.append(ds1) let ds2 = RadarChartDataSet(values: yse2, label: "World") ds2.colors = [NSUIColor.blue] - data.addDataSet(ds2) + data.append(ds2) self.radarChartView.data = data self.radarChartView.chartDescription.text = "Radarchart Demo" diff --git a/ChartsDemo/Swift/DemoBaseViewController.swift b/ChartsDemo/Swift/DemoBaseViewController.swift index dcbd28026b..82265eb594 100644 --- a/ChartsDemo/Swift/DemoBaseViewController.swift +++ b/ChartsDemo/Swift/DemoBaseViewController.swift @@ -117,13 +117,13 @@ class DemoBaseViewController: UIViewController, ChartViewDelegate { func handleOption(_ option: Option, forChartView chartView: ChartViewBase) { switch option { case .toggleValues: - for set in chartView.data!.dataSets { + for set in chartView.data! { set.drawValuesEnabled = !set.drawValuesEnabled } chartView.setNeedsDisplay() case .toggleIcons: - for set in chartView.data!.dataSets { + for set in chartView.data! { set.drawIconsEnabled = !set.drawIconsEnabled } chartView.setNeedsDisplay() @@ -159,7 +159,7 @@ class DemoBaseViewController: UIViewController, ChartViewDelegate { updateChartData() case .toggleBarBorders: - for set in chartView.data!.dataSets { + for set in chartView.data! { if let set = set as? BarChartDataSet { set.barBorderWidth = set.barBorderWidth == 1.0 ? 0.0 : 1.0 } diff --git a/ChartsDemo/Swift/Demos/AnotherBarChartViewController.swift b/ChartsDemo/Swift/Demos/AnotherBarChartViewController.swift index 878c5f011f..1f2bb4f609 100644 --- a/ChartsDemo/Swift/Demos/AnotherBarChartViewController.swift +++ b/ChartsDemo/Swift/Demos/AnotherBarChartViewController.swift @@ -66,7 +66,7 @@ class AnotherBarChartViewController: DemoBaseViewController { } var set1: BarChartDataSet! = nil - if let set = chartView.data?.dataSets.first as? BarChartDataSet { + if let set = chartView.data?.first as? BarChartDataSet { set1 = set set1?.values = yVals chartView.data?.notifyDataChanged() diff --git a/ChartsDemo/Swift/Demos/BarChartViewController.swift b/ChartsDemo/Swift/Demos/BarChartViewController.swift index a9a629120a..60be8856c1 100644 --- a/ChartsDemo/Swift/Demos/BarChartViewController.swift +++ b/ChartsDemo/Swift/Demos/BarChartViewController.swift @@ -119,7 +119,7 @@ class BarChartViewController: DemoBaseViewController { } var set1: BarChartDataSet! = nil - if let set = chartView.data?.dataSets.first as? BarChartDataSet { + if let set = chartView.data?.first as? BarChartDataSet { set1 = set set1.values = yVals chartView.data?.notifyDataChanged() diff --git a/ChartsDemo/Swift/Demos/BubbleChartViewController.swift b/ChartsDemo/Swift/Demos/BubbleChartViewController.swift index 39af2f5b5f..b06aeb9d23 100644 --- a/ChartsDemo/Swift/Demos/BubbleChartViewController.swift +++ b/ChartsDemo/Swift/Demos/BubbleChartViewController.swift @@ -104,7 +104,7 @@ class BubbleChartViewController: DemoBaseViewController { set3.setColor(ChartColorTemplates.colorful()[2], alpha: 0.5) set3.drawValuesEnabled = true - let data = BubbleChartData(dataSets: [set1, set2, set3]) + let data = [set1, set2, set3] as BubbleChartData data.setDrawValues(false) data.setValueFont(UIFont(name: "HelveticaNeue-Light", size: 7)!) data.setHighlightCircleWidth(1.5) diff --git a/ChartsDemo/Swift/Demos/CandleStickChartViewController.swift b/ChartsDemo/Swift/Demos/CandleStickChartViewController.swift index ef4dc5ac4c..e3b7418fef 100644 --- a/ChartsDemo/Swift/Demos/CandleStickChartViewController.swift +++ b/ChartsDemo/Swift/Demos/CandleStickChartViewController.swift @@ -104,7 +104,7 @@ class CandleStickChartViewController: DemoBaseViewController { override func optionTapped(_ option: Option) { if .toggleShadowColorSameAsCandle ~= option { - for set in chartView.data!.dataSets as! [CandleChartDataSet] { + for case let set as CandleChartDataSet in chartView.data! { set.shadowColorSameAsCandle = !set.shadowColorSameAsCandle } chartView.notifyDataSetChanged() diff --git a/ChartsDemo/Swift/Demos/CombinedChartViewController.swift b/ChartsDemo/Swift/Demos/CombinedChartViewController.swift index f4e2dc3dd9..82d26e6523 100644 --- a/ChartsDemo/Swift/Demos/CombinedChartViewController.swift +++ b/ChartsDemo/Swift/Demos/CombinedChartViewController.swift @@ -94,7 +94,7 @@ class CombinedChartViewController: DemoBaseViewController { override func optionTapped(_ option: Option) { switch option { case .toggleLineValues: - for set in chartView.data!.dataSets { + for set in chartView.data! { if let set = set as? LineChartDataSet { set.drawValuesEnabled = !set .drawValuesEnabled @@ -103,7 +103,7 @@ class CombinedChartViewController: DemoBaseViewController { chartView.setNeedsDisplay() case .toggleBarValues: - for set in chartView.data!.dataSets { + for set in chartView.data! { if let set = set as? BarChartDataSet { set.drawValuesEnabled = !set .drawValuesEnabled } @@ -171,7 +171,7 @@ class CombinedChartViewController: DemoBaseViewController { let barWidth = 0.45 // x2 dataset // (0.45 + 0.02) * 2 + 0.06 = 1.00 -> interval per "group" - let data = BarChartData(dataSets: [set1, set2]) + let data: BarChartData = [set1, set2] data.barWidth = barWidth // make this BarData object grouped diff --git a/ChartsDemo/Swift/Demos/CubicLineChartViewController.swift b/ChartsDemo/Swift/Demos/CubicLineChartViewController.swift index 5029456988..320b02e2c0 100644 --- a/ChartsDemo/Swift/Demos/CubicLineChartViewController.swift +++ b/ChartsDemo/Swift/Demos/CubicLineChartViewController.swift @@ -109,33 +109,35 @@ class CubicLineChartViewController: DemoBaseViewController { } override func optionTapped(_ option: Option) { + guard let data = chartView.data else { return } + switch option { case .toggleFilled: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.drawFilledEnabled = !set.drawFilledEnabled } chartView.setNeedsDisplay() case .toggleCircles: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.drawCirclesEnabled = !set.drawCirclesEnabled } chartView.setNeedsDisplay() case .toggleCubic: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .cubicBezier) ? .linear : .cubicBezier } chartView.setNeedsDisplay() case .toggleStepped: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .stepped) ? .linear : .stepped } chartView.setNeedsDisplay() case .toggleHorizontalCubic: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .cubicBezier) ? .horizontalBezier : .cubicBezier } chartView.setNeedsDisplay() diff --git a/ChartsDemo/Swift/Demos/LineChart1ViewController.swift b/ChartsDemo/Swift/Demos/LineChart1ViewController.swift index 3ec69908bf..43c345d4c9 100644 --- a/ChartsDemo/Swift/Demos/LineChart1ViewController.swift +++ b/ChartsDemo/Swift/Demos/LineChart1ViewController.swift @@ -142,33 +142,35 @@ class LineChart1ViewController: DemoBaseViewController { } override func optionTapped(_ option: Option) { + guard let data = chartView.data else { return } + switch option { case .toggleFilled: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.drawFilledEnabled = !set.drawFilledEnabled } chartView.setNeedsDisplay() case .toggleCircles: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.drawCirclesEnabled = !set.drawCirclesEnabled } chartView.setNeedsDisplay() case .toggleCubic: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .cubicBezier) ? .linear : .cubicBezier } chartView.setNeedsDisplay() case .toggleStepped: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .stepped) ? .linear : .stepped } chartView.setNeedsDisplay() case .toggleHorizontalCubic: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .cubicBezier) ? .horizontalBezier : .cubicBezier } chartView.setNeedsDisplay() diff --git a/ChartsDemo/Swift/Demos/LineChart2ViewController.swift b/ChartsDemo/Swift/Demos/LineChart2ViewController.swift index 63bdfe06c3..3132199f91 100644 --- a/ChartsDemo/Swift/Demos/LineChart2ViewController.swift +++ b/ChartsDemo/Swift/Demos/LineChart2ViewController.swift @@ -135,7 +135,7 @@ class LineChart2ViewController: DemoBaseViewController { set3.highlightColor = UIColor(red: 244/255, green: 117/255, blue: 117/255, alpha: 1) set3.drawCircleHoleEnabled = false - let data = LineChartData(dataSets: [set1, set2, set3]) + let data: LineChartData = [set1, set2, set3] data.setValueTextColor(.white) data.setValueFont(.systemFont(ofSize: 9)) @@ -143,33 +143,35 @@ class LineChart2ViewController: DemoBaseViewController { } override func optionTapped(_ option: Option) { + guard let data = chartView.data else { return } + switch option { case .toggleFilled: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.drawFilledEnabled = !set.drawFilledEnabled } chartView.setNeedsDisplay() case .toggleCircles: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.drawCirclesEnabled = !set.drawCirclesEnabled } chartView.setNeedsDisplay() case .toggleCubic: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .cubicBezier) ? .linear : .cubicBezier } chartView.setNeedsDisplay() case .toggleStepped: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .stepped) ? .linear : .stepped } chartView.setNeedsDisplay() case .toggleHorizontalCubic: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .cubicBezier) ? .horizontalBezier : .cubicBezier } chartView.setNeedsDisplay() diff --git a/ChartsDemo/Swift/Demos/LineChartFilledViewController.swift b/ChartsDemo/Swift/Demos/LineChartFilledViewController.swift index 76cdd6aadc..8c8c82ebd0 100644 --- a/ChartsDemo/Swift/Demos/LineChartFilledViewController.swift +++ b/ChartsDemo/Swift/Demos/LineChartFilledViewController.swift @@ -102,7 +102,7 @@ class LineChartFilledViewController: DemoBaseViewController { return CGFloat(self.chartView.leftAxis.axisMaximum) } - let data = LineChartData(dataSets: [set1, set2]) + let data: LineChartData = [set1, set2] data.setDrawValues(false) chartView.data = data diff --git a/ChartsDemo/Swift/Demos/LineChartTimeViewController.swift b/ChartsDemo/Swift/Demos/LineChartTimeViewController.swift index cf5654a12d..554e6354f0 100644 --- a/ChartsDemo/Swift/Demos/LineChartTimeViewController.swift +++ b/ChartsDemo/Swift/Demos/LineChartTimeViewController.swift @@ -118,33 +118,35 @@ class LineChartTimeViewController: DemoBaseViewController { } override func optionTapped(_ option: Option) { + guard let data = chartView.data else { return } + switch option { case .toggleFilled: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.drawFilledEnabled = !set.drawFilledEnabled } chartView.setNeedsDisplay() case .toggleCircles: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.drawCirclesEnabled = !set.drawCirclesEnabled } chartView.setNeedsDisplay() case .toggleCubic: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .cubicBezier) ? .linear : .cubicBezier } chartView.setNeedsDisplay() case .toggleStepped: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .stepped) ? .linear : .stepped } chartView.setNeedsDisplay() case .toggleHorizontalCubic: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .cubicBezier) ? .horizontalBezier : .cubicBezier } chartView.setNeedsDisplay() diff --git a/ChartsDemo/Swift/Demos/MultipleBarChartViewController.swift b/ChartsDemo/Swift/Demos/MultipleBarChartViewController.swift index 0390ac97bf..35cbacc2eb 100644 --- a/ChartsDemo/Swift/Demos/MultipleBarChartViewController.swift +++ b/ChartsDemo/Swift/Demos/MultipleBarChartViewController.swift @@ -119,7 +119,7 @@ class MultipleBarChartViewController: DemoBaseViewController { let set4 = BarChartDataSet(values: yVals4, label: "Company D") set4.setColor(UIColor(red: 255/255, green: 102/255, blue: 0/255, alpha: 1)) - let data = BarChartData(dataSets: [set1, set2, set3, set4]) + let data: BarChartData = [set1, set2, set3, set4] data.setValueFont(.systemFont(ofSize: 10, weight: .light)) data.setValueFormatter(LargeValueFormatter()) diff --git a/ChartsDemo/Swift/Demos/MultipleLinesChartViewController.swift b/ChartsDemo/Swift/Demos/MultipleLinesChartViewController.swift index bbf42bbdf1..c358e8b3a2 100644 --- a/ChartsDemo/Swift/Demos/MultipleLinesChartViewController.swift +++ b/ChartsDemo/Swift/Demos/MultipleLinesChartViewController.swift @@ -99,27 +99,29 @@ class MultipleLinesChartViewController: DemoBaseViewController { } override func optionTapped(_ option: Option) { + guard let data = chartView.data else { return } + switch option { case .toggleFilled: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.drawFilledEnabled = !set.drawFilledEnabled } chartView.setNeedsDisplay() case .toggleCircles: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.drawCirclesEnabled = !set.drawCirclesEnabled } chartView.setNeedsDisplay() case .toggleCubic: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .cubicBezier) ? .linear : .cubicBezier } chartView.setNeedsDisplay() case .toggleStepped: - for set in chartView.data!.dataSets as! [LineChartDataSet] { + for case let set as LineChartDataSet in data { set.mode = (set.mode == .stepped) ? .linear : .stepped } chartView.setNeedsDisplay() diff --git a/ChartsDemo/Swift/Demos/RadarChartViewController.swift b/ChartsDemo/Swift/Demos/RadarChartViewController.swift index ac4a7599d8..1d680293b3 100644 --- a/ChartsDemo/Swift/Demos/RadarChartViewController.swift +++ b/ChartsDemo/Swift/Demos/RadarChartViewController.swift @@ -142,7 +142,7 @@ class RadarChartViewController: DemoBaseViewController { set2.drawHighlightCircleEnabled = true set2.setDrawHighlightIndicators(false) - let data = RadarChartData(dataSets: [set1, set2]) + let data: RadarChartData = [set1, set2] data.setValueFont(.systemFont(ofSize: 8, weight: .light)) data.setDrawValues(false) data.setValueTextColor(.white) @@ -151,6 +151,8 @@ class RadarChartViewController: DemoBaseViewController { } override func optionTapped(_ option: Option) { + guard let data = chartView.data else { return } + switch option { case .toggleXLabels: chartView.xAxis.drawLabelsEnabled = !chartView.xAxis.drawLabelsEnabled @@ -166,14 +168,14 @@ class RadarChartViewController: DemoBaseViewController { chartView.rotationEnabled = !chartView.rotationEnabled case .toggleFilled: - for set in chartView.data!.dataSets as! [RadarChartDataSet] { + for case let set as RadarChartDataSet in data { set.drawFilledEnabled = !set.drawFilledEnabled } chartView.setNeedsDisplay() case .toggleHighlightCircle: - for set in chartView.data!.dataSets as! [RadarChartDataSet] { + for case let set as RadarChartDataSet in data { set.drawHighlightCircleEnabled = !set.drawHighlightCircleEnabled } chartView.setNeedsDisplay() diff --git a/ChartsDemo/Swift/Demos/ScatterChartViewController.swift b/ChartsDemo/Swift/Demos/ScatterChartViewController.swift index 19479670ee..64bc46ccba 100644 --- a/ChartsDemo/Swift/Demos/ScatterChartViewController.swift +++ b/ChartsDemo/Swift/Demos/ScatterChartViewController.swift @@ -105,7 +105,7 @@ class ScatterChartViewController: DemoBaseViewController { set3.setColor(ChartColorTemplates.colorful()[2]) set3.scatterShapeSize = 8 - let data = ScatterChartData(dataSets: [set1, set2, set3]) + let data: ScatterChartData = [set1, set2, set3] data.setValueFont(.systemFont(ofSize: 7, weight: .light)) chartView.data = data diff --git a/Source/Charts/Charts/ChartViewBase.swift b/Source/Charts/Charts/ChartViewBase.swift index 7665c896f7..abca440d61 100644 --- a/Source/Charts/Charts/ChartViewBase.swift +++ b/Source/Charts/Charts/ChartViewBase.swift @@ -210,8 +210,7 @@ open class ChartViewBase: NSUIView, ChartDataProvider, AnimatorDelegate /// - returns: `true` if the chart is empty (meaning it's data object is either null or contains no entries). @objc open func isEmpty() -> Bool { - guard let data = data else { return true } - return data.entryCount <= 0 + return data?.isEmpty ?? true } /// Lets the chart know its underlying data has changed and should perform all necessary recalculations. @@ -251,13 +250,11 @@ open class ChartViewBase: NSUIView, ChartDataProvider, AnimatorDelegate } - if defaultValueFormatter is DefaultValueFormatter + if let formatter = defaultValueFormatter as? DefaultValueFormatter { // setup the formatter with a new number of digits let digits = reference.decimalPlaces - - (defaultValueFormatter as? DefaultValueFormatter)?.decimals - = digits + formatter.decimals = digits } } diff --git a/Source/Charts/Data/Implementations/Standard/BarChartData.swift b/Source/Charts/Data/Implementations/Standard/BarChartData.swift index 8bffa305da..6516428275 100644 --- a/Source/Charts/Data/Implementations/Standard/BarChartData.swift +++ b/Source/Charts/Data/Implementations/Standard/BarChartData.swift @@ -43,13 +43,11 @@ open class BarChartData: BarLineScatterCandleBubbleChartData /// - parameter barSpace: The space between individual bars in values (not pixels) e.g. 0.1f for bar width 1f @objc open func groupBars(fromX: Double, groupSpace: Double, barSpace: Double) { - let setCount = _dataSets.count - if setCount <= 1 - { + guard !isEmpty else { print("BarData needs to hold at least 2 BarDataSets to allow grouping.", terminator: "\n") return } - + let max = maxEntryCountSet let maxEntryCount = max?.entryCount ?? 0 @@ -61,7 +59,7 @@ open class BarChartData: BarLineScatterCandleBubbleChartData let interval = groupWidth(groupSpace: groupSpace, barSpace: barSpace) - for i in stride(from: 0, to: maxEntryCount, by: 1) + for i in 0.. Double { - return Double(_dataSets.count) * (self.barWidth + barSpace) + groupSpace + return Double(count) * (self.barWidth + barSpace) + groupSpace } - } diff --git a/Source/Charts/Data/Implementations/Standard/ChartData.swift b/Source/Charts/Data/Implementations/Standard/ChartData.swift index 5acb2ea926..b4b7dfbedd 100644 --- a/Source/Charts/Data/Implementations/Standard/ChartData.swift +++ b/Source/Charts/Data/Implementations/Standard/ChartData.swift @@ -66,10 +66,7 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral @objc open func calcMinMaxY(fromX: Double, toX: Double) { - for set in _dataSets - { - set.calcMinMaxY(fromX: fromX, toX: toX) - } + forEach { $0.calcMinMaxY(fromX: fromX, toX: toX) } // apply the new data calcMinMax() @@ -83,10 +80,7 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral _xMax = -Double.greatestFiniteMagnitude _xMin = Double.greatestFiniteMagnitude - for set in _dataSets - { - calcMinMax(dataSet: set) - } + forEach { calcMinMax(dataSet: $0) } _leftAxisMax = -Double.greatestFiniteMagnitude _leftAxisMin = Double.greatestFiniteMagnitude @@ -100,20 +94,17 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral { _leftAxisMax = firstLeft!.yMax _leftAxisMin = firstLeft!.yMin - - for dataSet in _dataSets + + for dataSet in _dataSets where dataSet.axisDependency == .left { - if dataSet.axisDependency == .left + if dataSet.yMin < _leftAxisMin { - if dataSet.yMin < _leftAxisMin - { - _leftAxisMin = dataSet.yMin - } - - if dataSet.yMax > _leftAxisMax - { - _leftAxisMax = dataSet.yMax - } + _leftAxisMin = dataSet.yMin + } + + if dataSet.yMax > _leftAxisMax + { + _leftAxisMax = dataSet.yMax } } } @@ -126,19 +117,16 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral _rightAxisMax = firstRight!.yMax _rightAxisMin = firstRight!.yMin - for dataSet in _dataSets + for dataSet in _dataSets where dataSet.axisDependency == .right { - if dataSet.axisDependency == .right + if dataSet.yMin < _rightAxisMin + { + _rightAxisMin = dataSet.yMin + } + + if dataSet.yMax > _rightAxisMax { - if dataSet.yMin < _rightAxisMin - { - _rightAxisMin = dataSet.yMin - } - - if dataSet.yMax > _rightAxisMax - { - _rightAxisMax = dataSet.yMax - } + _rightAxisMax = dataSet.yMax } } } @@ -359,50 +347,15 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral /// - returns: The index of the DataSet Object with the given label. Sensitive or not. internal func getDataSetIndexByLabel(_ label: String, ignorecase: Bool) -> Int { - if ignorecase - { - for i in 0 ..< dataSets.count - { - if dataSets[i].label == nil - { - continue - } - if (label.caseInsensitiveCompare(dataSets[i].label!) == ComparisonResult.orderedSame) - { - return i - } - } - } - else - { - for i in 0 ..< dataSets.count - { - if label == dataSets[i].label - { - return i - } - } - } - - return -1 + return ignorecase + ? index { $0.label?.caseInsensitiveCompare(label) == .orderedSame } ?? -1 + : index { $0.label == label } ?? -1 } /// - returns: The labels of all DataSets as a string array. internal func dataSetLabels() -> [String] { - var types = [String]() - - for i in 0 ..< _dataSets.count - { - if dataSets[i].label == nil - { - continue - } - - types[i] = _dataSets[i].label! - } - - return types + return flatMap { $0.label } } /// Get the Entry for a corresponding highlight object @@ -411,14 +364,8 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral /// - returns: The entry that is highlighted @objc open func entryForHighlight(_ highlight: Highlight) -> ChartDataEntry? { - if highlight.dataSetIndex >= dataSets.count - { - return nil - } - else - { - return dataSets[highlight.dataSetIndex].entryForXValue(highlight.x, closestToY: highlight.y) - } + guard indices.contains(highlight.dataSetIndex) else { return nil } + return self[highlight.dataSetIndex].entryForXValue(highlight.x, closestToY: highlight.y) } /// **IMPORTANT: This method does calculations at runtime. Use with care in performance critical situations.** @@ -426,87 +373,45 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral /// - parameter label: /// - parameter ignorecase: /// - returns: The DataSet Object with the given label. Sensitive or not. - @objc open func getDataSetByLabel(_ label: String, ignorecase: Bool) -> ChartDataSetProtocol? + @objc open func getDataSetByLabel(_ label: String, ignorecase: Bool) -> Element? { - let index = getDataSetIndexByLabel(label, ignorecase: ignorecase) - - if index < 0 || index >= _dataSets.count - { - return nil - } - else - { - return _dataSets[index] - } + guard let index = index(forLabel: label, ignoreCase: ignorecase) else { return nil } + return self[index] } - @objc open func getDataSetByIndex(_ index: Int) -> ChartDataSetProtocol! + @objc open func getDataSetByIndex(_ index: Index) -> Element! { if index < 0 || index >= _dataSets.count { return nil } - return _dataSets[index] - } - - @objc open func addDataSet(_ dataSet: ChartDataSetProtocol!) - { - calcMinMax(dataSet: dataSet) - - _dataSets.append(dataSet) + return self[index] } - + /// Removes the given DataSet from this data object. /// Also recalculates all minimum and maximum values. /// /// - returns: `true` if a DataSet was removed, `false` ifno DataSet could be removed. - @objc @discardableResult open func removeDataSet(_ dataSet: ChartDataSetProtocol!) -> Bool + @objc @discardableResult open func removeDataSet(_ dataSet: Element!) -> Bool { - if dataSet === nil - { - return false - } - - for i in 0 ..< _dataSets.count - { - if _dataSets[i] === dataSet - { - return removeDataSetByIndex(i) - } - } - - return false - } - - /// Removes the DataSet at the given index in the DataSet array from the data object. - /// Also recalculates all minimum and maximum values. - /// - /// - returns: `true` if a DataSet was removed, `false` ifno DataSet could be removed. - @objc @discardableResult open func removeDataSetByIndex(_ index: Int) -> Bool - { - if index >= _dataSets.count || index < 0 - { - return false - } - - _dataSets.remove(at: index) - - calcMinMax() - + guard + dataSet != nil, + let index = index(where: { $0 === dataSet }) + else { return false } + + _ = remove(at: index) return true } - + /// Adds an Entry to the DataSet at the specified index. Entries are added to the end of the list. @objc(addEntry:dataSetIndex:) open func appendEntry(_ e: ChartDataEntry, toDataSet dataSetIndex: Index) { - guard indices.contains(dataSetIndex) else - { - print("ChartData.addEntry() - Cannot add Entry because dataSetIndex too high or too low.", terminator: "\n") - return + guard indices.contains(dataSetIndex) else { + return print("ChartData.addEntry() - Cannot add Entry because dataSetIndex too high or too low.", terminator: "\n") } - + let set = self[dataSetIndex] if !set.addEntry(e) { return } calcMinMax(entry: e, axis: set.axisDependency) @@ -515,14 +420,10 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral /// Removes the given Entry object from the DataSet at the specified index. @objc @discardableResult open func removeEntry(_ entry: ChartDataEntry, dataSetIndex: Int) -> Bool { - // entry outofbounds - if dataSetIndex >= _dataSets.count - { - return false - } - + guard indices.contains(dataSetIndex) else { return false } + // remove the entry from the dataset - let removed = _dataSets[dataSetIndex].removeEntry(entry) + let removed = self[dataSetIndex].removeEntry(entry) if removed { @@ -537,105 +438,45 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral /// - returns: `true` if an entry was removed, `false` ifno Entry was found that meets the specified requirements. @objc @discardableResult open func removeEntry(xValue: Double, dataSetIndex: Int) -> Bool { - if dataSetIndex >= _dataSets.count - { - return false - } - - if let entry = _dataSets[dataSetIndex].entryForXValue(xValue, closestToY: Double.nan) - { - return removeEntry(entry, dataSetIndex: dataSetIndex) - } - - return false + guard + indices.contains(dataSetIndex), + let entry = self[dataSetIndex].entryForXValue(xValue, closestToY: .nan) + else { return false } + + return removeEntry(entry, dataSetIndex: dataSetIndex) } /// - returns: The DataSet that contains the provided Entry, or null, if no DataSet contains this entry. @objc open func getDataSetForEntry(_ e: ChartDataEntry!) -> ChartDataSetProtocol? { - if e == nil - { - return nil - } - - for i in 0 ..< _dataSets.count - { - let set = _dataSets[i] - - if e === set.entryForXValue(e.x, closestToY: e.y) - { - return set - } - } - - return nil + guard e != nil else { return nil } + + return first { $0.entryForXValue(e.x, closestToY: e.y) === e } } /// - returns: The index of the provided DataSet in the DataSet array of this data object, or -1 if it does not exist. @objc open func indexOfDataSet(_ dataSet: ChartDataSetProtocol) -> Int { - for i in 0 ..< _dataSets.count - { - if _dataSets[i] === dataSet - { - return i - } - } - - return -1 + return index(where: { $0 === dataSet }) ?? -1 } /// - returns: The first DataSet from the datasets-array that has it's dependency on the left axis. Returns null if no DataSet with left dependency could be found. @objc open func getFirstLeft(dataSets: [ChartDataSetProtocol]) -> ChartDataSetProtocol? { - for dataSet in dataSets - { - if dataSet.axisDependency == .left - { - return dataSet - } - } - - return nil + return first { $0.axisDependency == .left } } /// - returns: The first DataSet from the datasets-array that has it's dependency on the right axis. Returns null if no DataSet with right dependency could be found. @objc open func getFirstRight(dataSets: [ChartDataSetProtocol]) -> ChartDataSetProtocol? { - for dataSet in _dataSets - { - if dataSet.axisDependency == .right - { - return dataSet - } - } - - return nil + return first { $0.axisDependency == .right } } /// - returns: All colors used across all DataSet objects this object represents. + // TODO: This should return a non-optional array @objc open func getColors() -> [NSUIColor]? { - var clrcnt = 0 - - for i in 0 ..< _dataSets.count - { - clrcnt += _dataSets[i].colors.count - } - - var colors = [NSUIColor]() - - for i in 0 ..< _dataSets.count - { - let clrs = _dataSets[i].colors - - for clr in clrs - { - colors.append(clr) - } - } - - return colors + return flatMap { $0.colors.map { $0 } } } /// Sets a custom ValueFormatter for all DataSets this data object contains. @@ -643,38 +484,26 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral { guard let formatter = formatter else { return } - - for set in dataSets - { - set.valueFormatter = formatter - } + + forEach { $0.valueFormatter = formatter } } /// Sets the color of the value-text (color in which the value-labels are drawn) for all DataSets this data object contains. @objc open func setValueTextColor(_ color: NSUIColor!) { - for set in dataSets - { - set.valueTextColor = color ?? set.valueTextColor - } + forEach { $0.valueTextColor = color ?? $0.valueTextColor } } /// Sets the font for all value-labels for all DataSets this data object contains. @objc open func setValueFont(_ font: NSUIFont!) { - for set in dataSets - { - set.valueFont = font ?? set.valueFont - } + forEach { $0.valueFont = font ?? $0.valueFont } } /// Enables / disables drawing values (value-text) for all DataSets this data object contains. @objc open func setDrawValues(_ enabled: Bool) { - for set in dataSets - { - set.drawValuesEnabled = enabled - } + forEach { $0.drawValuesEnabled = enabled } } /// Enables / disables highlighting values for all DataSets this data object contains. @@ -683,22 +512,11 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral { get { - for set in dataSets - { - if !set.highlightEnabled - { - return false - } - } - - return true + return first { $0.highlightEnabled == false } == nil } set { - for set in dataSets - { - set.highlightEnabled = newValue - } + forEach { $0.highlightEnabled = newValue } } } @@ -717,49 +535,19 @@ open class ChartData: NSObject, ExpressibleByArrayLiteral /// - returns: `true` if so, `false` ifnot. @objc open func contains(dataSet: ChartDataSetProtocol) -> Bool { - for set in dataSets - { - if set === dataSet - { - return true - } - } - - return false + return contains { $0 === dataSet } } /// - returns: The total entry count across all DataSet objects this data object contains. @objc open var entryCount: Int { - var count = 0 - - for set in _dataSets - { - count += set.entryCount - } - - return count + return reduce(0) { return $0 + $1.entryCount } } /// - returns: The DataSet object with the maximum number of entries or null if there are no DataSets. @objc open var maxEntryCountSet: ChartDataSetProtocol? { - if _dataSets.count == 0 - { - return nil - } - - var max = _dataSets[0] - - for set in _dataSets - { - if set.entryCount > max.entryCount - { - max = set - } - } - - return max + return self.max { $0.entryCount > $1.entryCount } } } @@ -803,24 +591,16 @@ extension ChartData: RandomAccessCollection // MARK: RangeReplaceableCollection extension ChartData: RangeReplaceableCollection { + @objc(addDataSet:) public func append(_ newElement: Element) { - guard !(self is CombinedChartData) else - { - fatalError("append(_:) not supported for CombinedData") - } - _dataSets.append(newElement) calcMinMax(dataSet: newElement) } + @objc(removeDataSetByIndex:) public func remove(at position: Index) -> Element { - guard !(self is CombinedChartData) else - { - fatalError("remove(at:) not supported for CombinedData") - } - let element = _dataSets.remove(at: position) calcMinMax() return element @@ -872,7 +652,7 @@ extension ChartData: RangeReplaceableCollection notifyDataChanged() } - public func removeSubrange(_ bounds: R) where R : RangeExpression, ChartData.Index == R.Bound + public func removeSubrange(_ bounds: R) where R : RangeExpression, Index == R.Bound { guard !(self is CombinedChartData) else { @@ -893,6 +673,17 @@ extension ChartData: RangeReplaceableCollection _dataSets.removeAll(keepingCapacity: keepCapacity) notifyDataChanged() } + + public func replaceSubrange(_ subrange: Swift.Range, with newElements: C) where C : Collection, Element == C.Element + { + guard !(self is CombinedChartData) else + { + fatalError("replaceSubrange(_:) not supported for CombinedData") + } + + _dataSets.replaceSubrange(subrange, with: newElements) + newElements.forEach { self.calcMinMax(dataSet: $0) } + } } // MARK: Swift Accessors diff --git a/Source/Charts/Data/Implementations/Standard/CombinedChartData.swift b/Source/Charts/Data/Implementations/Standard/CombinedChartData.swift index 4eaac60f34..23e6992ebe 100644 --- a/Source/Charts/Data/Implementations/Standard/CombinedChartData.swift +++ b/Source/Charts/Data/Implementations/Standard/CombinedChartData.swift @@ -227,13 +227,7 @@ open class CombinedChartData: BarLineScatterCandleBubbleChartData return success } - - open override func removeDataSetByIndex(_ index: Int) -> Bool - { - print("removeDataSet(index) not supported for CombinedData", terminator: "\n") - return false - } - + open override func removeEntry(_ entry: ChartDataEntry, dataSetIndex: Int) -> Bool { print("removeEntry(entry, dataSetIndex) not supported for CombinedData", terminator: "\n") @@ -248,27 +242,12 @@ open class CombinedChartData: BarLineScatterCandleBubbleChartData open override func notifyDataChanged() { - if _lineData !== nil - { - _lineData.notifyDataChanged() - } - if _barData !== nil - { - _barData.notifyDataChanged() - } - if _scatterData !== nil - { - _scatterData.notifyDataChanged() - } - if _candleData !== nil - { - _candleData.notifyDataChanged() - } - if _bubbleData !== nil - { - _bubbleData.notifyDataChanged() - } - + _lineData?.notifyDataChanged() + _barData?.notifyDataChanged() + _scatterData?.notifyDataChanged() + _candleData?.notifyDataChanged() + _bubbleData?.notifyDataChanged() + super.notifyDataChanged() // recalculate everything } @@ -322,4 +301,14 @@ open class CombinedChartData: BarLineScatterCandleBubbleChartData return data.dataSets[highlight.dataSetIndex] } + + // MARK: Unsupported Collection Methods + + public override func append(_ newElement: ChartData.Element) { + fatalError("append(_:) not supported for CombinedData") + } + + public override func remove(at i: Int) -> ChartDataSetProtocol { + fatalError("remove(at:) not supported for CombinedData") + } } diff --git a/Source/Charts/Data/Implementations/Standard/PieChartData.swift b/Source/Charts/Data/Implementations/Standard/PieChartData.swift index 1ea1f2675a..5ee2f4347e 100644 --- a/Source/Charts/Data/Implementations/Standard/PieChartData.swift +++ b/Source/Charts/Data/Implementations/Standard/PieChartData.swift @@ -85,25 +85,6 @@ open class PieChartData: ChartData return dataSet?.entryForIndex(Int(highlight.x)) } - open override func addDataSet(_ d: ChartDataSetProtocol!) - { - super.addDataSet(d) - } - - /// Removes the DataSet at the given index in the DataSet array from the data object. - /// Also recalculates all minimum and maximum values. - /// - /// - returns: `true` if a DataSet was removed, `false` ifno DataSet could be removed. - open override func removeDataSetByIndex(_ index: Int) -> Bool - { - if index >= _dataSets.count || index < 0 - { - return false - } - - return false - } - /// - returns: The total y-value sum across all DataSet objects the this object represents. @objc open var yValueSum: Double { diff --git a/Source/Charts/Data/Implementations/Standard/ScatterChartData.swift b/Source/Charts/Data/Implementations/Standard/ScatterChartData.swift index c3c4ca1b8a..b30304a1b2 100644 --- a/Source/Charts/Data/Implementations/Standard/ScatterChartData.swift +++ b/Source/Charts/Data/Implementations/Standard/ScatterChartData.swift @@ -32,22 +32,14 @@ open class ScatterChartData: BarLineScatterCandleBubbleChartData /// - returns: The maximum shape-size across all DataSets. @objc open func getGreatestShapeSize() -> CGFloat { - var max = CGFloat(0.0) - - for set in _dataSets - { - let scatterDataSet = set as? ScatterChartDataSetProtocol - - if scatterDataSet == nil - { + return reduce(0) { (max, set) -> CGFloat in + guard let set = set as? ScatterChartDataSetProtocol else { print("ScatterChartData: Found a DataSet which is not a ScatterChartDataSet", terminator: "\n") + + return max } - else if let size = scatterDataSet?.scatterShapeSize, size > max - { - max = size - } + + return Swift.max(max, set.scatterShapeSize) } - - return max } } diff --git a/Source/Charts/Highlight/ChartHighlighter.swift b/Source/Charts/Highlight/ChartHighlighter.swift index c62c2a8365..d22302cf45 100644 --- a/Source/Charts/Highlight/ChartHighlighter.swift +++ b/Source/Charts/Highlight/ChartHighlighter.swift @@ -73,17 +73,11 @@ open class ChartHighlighter : NSObject, Highlighter guard let data = self.data else { return vals } - for i in 0 ..< data.dataSetCount - { - guard - let dataSet = data.getDataSetByIndex(i), - dataSet.isHighlightEnabled // don't include datasets that cannot be highlighted - else { continue } - - + for (i, set) in zip(data.indices, data) where set.isHighlightEnabled + { // extract all y-values from all DataSets at the given x-value. // some datasets (i.e bubble charts) make sense to have multiple values for an x-value. We'll have to find a way to handle that later on. It's more complicated now when x-indices are floating point. - vals.append(contentsOf: buildHighlights(dataSet: dataSet, dataSetIndex: i, xValue: xValue, rounding: .closest)) + vals.append(contentsOf: buildHighlights(dataSet: set, dataSetIndex: i, xValue: xValue, rounding: .closest)) } return vals