Skip to content

Commit

Permalink
Chartdata collection conformance (#3023)
Browse files Browse the repository at this point in the history
* Added Collection conformances

MutableCollection
RandomAccessCollection
RangeReplaceableCollection

* Fixed required initializers

* ChartData adopts ExressibleByArrayLiteral

* Updates for PR

Also added remove subrange.

* PR review fixes

* Removed unnecessary `get` from subscripts.

* Disabled `remove(at:)` for CombinedChartView

* Relocated `appendEntry(_:todataSet:)`

* Removed methods from CombinedChartData
  • Loading branch information
jjatie authored and liuxuan30 committed Jan 16, 2018
1 parent 28ed948 commit 4285bbc
Show file tree
Hide file tree
Showing 10 changed files with 240 additions and 28 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import CoreGraphics

open class BarChartData: BarLineScatterCandleBubbleChartData
{
public override init()
public required init()
{
super.init()
}
Expand All @@ -23,7 +23,12 @@ open class BarChartData: BarLineScatterCandleBubbleChartData
{
super.init(dataSets: dataSets)
}


public required init(arrayLiteral elements: ChartDataSetProtocol...)
{
super.init(dataSets: elements)
}

/// The width of the bars on the x-axis, in values (not pixels)
///
/// **default**: 0.85
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Foundation

open class BarLineScatterCandleBubbleChartData: ChartData
{
public override init()
public required init()
{
super.init()
}
Expand All @@ -22,4 +22,9 @@ open class BarLineScatterCandleBubbleChartData: ChartData
{
super.init(dataSets: dataSets)
}

public required init(arrayLiteral elements: ChartDataSetProtocol...)
{
super.init(dataSets: elements)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import CoreGraphics

open class BubbleChartData: BarLineScatterCandleBubbleChartData
{
public override init()
public required init()
{
super.init()
}
Expand All @@ -23,7 +23,12 @@ open class BubbleChartData: BarLineScatterCandleBubbleChartData
{
super.init(dataSets: dataSets)
}


public required init(arrayLiteral elements: ChartDataSetProtocol...)
{
super.init(dataSets: elements)
}

/// Sets the width of the circle that surrounds the bubble when highlighted for all DataSet objects this data object contains
@objc open func setHighlightCircleWidth(_ width: CGFloat)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Foundation

open class CandleChartData: BarLineScatterCandleBubbleChartData
{
public override init()
public required init()
{
super.init()
}
Expand All @@ -22,4 +22,9 @@ open class CandleChartData: BarLineScatterCandleBubbleChartData
{
super.init(dataSets: dataSets)
}

public required init(arrayLiteral elements: ChartDataSetProtocol...)
{
super.init(dataSets: elements)
}
}
199 changes: 183 additions & 16 deletions Source/Charts/Data/Implementations/Standard/ChartData.swift
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@

import Foundation

open class ChartData: NSObject
open class ChartData: NSObject, ExpressibleByArrayLiteral
{
internal var _yMax: Double = -Double.greatestFiniteMagnitude
internal var _yMin: Double = Double.greatestFiniteMagnitude
Expand All @@ -24,13 +24,20 @@ open class ChartData: NSObject

internal var _dataSets = [ChartDataSetProtocol]()

public override init()
public override required init()
{
super.init()

_dataSets = [ChartDataSetProtocol]()
}


public required init(arrayLiteral elements: ChartDataSetProtocol...)
{
super.init()

_dataSets = elements

self.initialize(dataSets: _dataSets)
}

@objc public init(dataSets: [ChartDataSetProtocol]?)
{
super.init()
Expand Down Expand Up @@ -491,22 +498,20 @@ open class ChartData: NSObject
}

/// Adds an Entry to the DataSet at the specified index. Entries are added to the end of the list.
@objc open func addEntry(_ e: ChartDataEntry, dataSetIndex: Int)
@objc(addEntry:dataSetIndex:)
open func appendEntry(_ e: ChartDataEntry, toDataSet dataSetIndex: Index)
{
if _dataSets.count > dataSetIndex && dataSetIndex >= 0
{
let set = _dataSets[dataSetIndex]

if !set.addEntry(e) { return }

calcMinMax(entry: e, axis: set.axisDependency)
}
else
guard indices.contains(dataSetIndex) else
{
print("ChartData.addEntry() - Cannot add Entry because dataSetIndex too high or too low.", terminator: "\n")
return
}

let set = self[dataSetIndex]
if !set.addEntry(e) { return }
calcMinMax(entry: e, axis: set.axisDependency)
}

/// Removes the given Entry object from the DataSet at the specified index.
@objc @discardableResult open func removeEntry(_ entry: ChartDataEntry, dataSetIndex: Int) -> Bool
{
Expand Down Expand Up @@ -757,3 +762,165 @@ open class ChartData: NSObject
return max
}
}

// MARK: MutableCollection
extension ChartData: MutableCollection
{
public typealias Index = Int
public typealias Element = ChartDataSetProtocol

public var startIndex: Index
{
return _dataSets.startIndex
}

public var endIndex: Index
{
return _dataSets.endIndex
}

public func index(after: Index) -> Index
{
return _dataSets.index(after: after)
}

public subscript(position: Index) -> Element
{
get{ return _dataSets[position] }
set{ self._dataSets[position] = newValue }
}
}

// MARK: RandomAccessCollection
extension ChartData: RandomAccessCollection
{
public func index(before: Index) -> Index
{
return _dataSets.index(before: before)
}
}

// MARK: RangeReplaceableCollection
extension ChartData: RangeReplaceableCollection
{
public func append(_ newElement: Element)
{
guard !(self is CombinedChartData) else
{
fatalError("append(_:) not supported for CombinedData")
}

_dataSets.append(newElement)
calcMinMax(dataSet: newElement)
}

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
}

public func removeFirst() -> Element
{
guard !(self is CombinedChartData) else
{
fatalError("removeFirst() not supported for CombinedData")
}

let element = _dataSets.removeFirst()
notifyDataChanged()
return element
}

public func removeFirst(_ n: Int)
{
guard !(self is CombinedChartData) else
{
fatalError("removeFirst(_:) not supported for CombinedData")
}

_dataSets.removeFirst(n)
notifyDataChanged()
}

public func removeLast() -> Element
{
guard !(self is CombinedChartData) else
{
fatalError("removeLast() not supported for CombinedData")
}

let element = _dataSets.removeLast()
notifyDataChanged()
return element
}

public func removeLast(_ n: Int)
{
guard !(self is CombinedChartData) else
{
fatalError("removeLast(_:) not supported for CombinedData")
}

_dataSets.removeLast(n)
notifyDataChanged()
}

public func removeSubrange<R>(_ bounds: R) where R : RangeExpression, ChartData.Index == R.Bound
{
guard !(self is CombinedChartData) else
{
fatalError("removeSubrange<R>(_:) not supported for CombinedData")
}

_dataSets.removeSubrange(bounds)
notifyDataChanged()
}

public func removeAll(keepingCapacity keepCapacity: Bool)
{
guard !(self is CombinedChartData) else
{
fatalError("removeAll(keepingCapacity:) not supported for CombinedData")
}

_dataSets.removeAll(keepingCapacity: keepCapacity)
notifyDataChanged()
}
}

// MARK: Swift Accessors
extension ChartData
{
/// Retrieve the index of a ChartDataSet with a specific label from the ChartData. Search can be case sensitive or not.
/// **IMPORTANT: This method does calculations at runtime, do not over-use in performance critical situations.**
///
/// - Parameters:
/// - label: The label to search for
/// - ignoreCase: if true, the search is not case-sensitive
/// - Returns: The index of the DataSet Object with the given label. `nil` if not found
public func index(forLabel label: String, ignoreCase: Bool) -> Index?
{
return ignoreCase
? index { $0.label?.caseInsensitiveCompare(label) == .orderedSame }
: index { $0.label == label }
}

public subscript(label: String, ignoreCase: Bool) -> Element?
{
guard let index = index(forLabel: label, ignoreCase: ignoreCase) else { return nil }
return self[index]
}

public subscript(entry: ChartDataEntry) -> Element?
{
guard let index = index(where: { $0.entryForXValue(entry.x, closestToY: entry.y) === entry }) else { return nil }
return self[index]
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ open class CombinedChartData: BarLineScatterCandleBubbleChartData
private var _candleData: CandleChartData!
private var _bubbleData: BubbleChartData!

public override init()
public required init()
{
super.init()
}
Expand All @@ -28,6 +28,11 @@ open class CombinedChartData: BarLineScatterCandleBubbleChartData
{
super.init(dataSets: dataSets)
}

public required init(arrayLiteral elements: ChartDataSetProtocol...)
{
super.init(dataSets: elements)
}

@objc open var lineData: LineChartData!
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import Foundation
/// Data object that encapsulates all data associated with a LineChart.
open class LineChartData: ChartData
{
public override init()
public required init()
{
super.init()
}
Expand All @@ -23,4 +23,9 @@ open class LineChartData: ChartData
{
super.init(dataSets: dataSets)
}

public required init(arrayLiteral elements: ChartDataSetProtocol...)
{
super.init(dataSets: elements)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import Foundation

open class PieChartData: ChartData
{
public override init()
public required init()
{
super.init()
}
Expand All @@ -23,6 +23,11 @@ open class PieChartData: ChartData
super.init(dataSets: dataSets)
}

public required init(arrayLiteral elements: ChartDataSetProtocol...)
{
super.init(dataSets: elements)
}

@objc var dataSet: PieChartDataSetProtocol?
{
get
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ open class RadarChartData: ChartData
self.labels = labels
}

public override init()
public required init()
{
super.init()
}
Expand All @@ -38,7 +38,12 @@ open class RadarChartData: ChartData
{
super.init(dataSets: dataSets)
}


public required init(arrayLiteral elements: ChartDataSetProtocol...)
{
super.init(dataSets: elements)
}

open override func entryForHighlight(_ highlight: Highlight) -> ChartDataEntry?
{
return getDataSetByIndex(highlight.dataSetIndex)?.entryForIndex(Int(highlight.x))
Expand Down
Loading

0 comments on commit 4285bbc

Please sign in to comment.