-
-
Notifications
You must be signed in to change notification settings - Fork 6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Chartdata collection conformance #3023
Changes from 4 commits
6e80eb0
36ca566
cb32b08
716f182
ca5afad
8976b95
f28d3d5
583dab6
c0b7d65
a71f87c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
|
@@ -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 = dataSets | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. is there any implicit declare of There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The first part is an error I will fix. Should be |
||
|
||
self.initialize(dataSets: _dataSets) | ||
} | ||
|
||
@objc public init(dataSets: [ChartDataSetProtocol]?) | ||
{ | ||
super.init() | ||
|
@@ -757,3 +764,138 @@ 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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I saw There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. From the
The index of the collection ( |
||
{ | ||
return _dataSets.index(before: before) | ||
} | ||
} | ||
|
||
// MARK: RangeReplaceableCollection | ||
extension ChartData: RangeReplaceableCollection | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Generally it should works fine with the collection protocol adoption. The devil may exist in CombinedChartData in the future, as it works differently than usual chart data. We actually don't append/remove data sets into a combined data, we just assign new sub chartData. e.g. open override func removeDataSetByIndex(_ index: Int) -> Bool
{
print("removeDataSet(index) not supported for CombinedData", terminator: "\n")
return false
} I think we should override the protocols in CombinedChartData to not allow such operations? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I will do that right now : ) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Fixed |
||
{ | ||
public func append(_ newElement: Element) | ||
{ | ||
self._dataSets.append(newElement) | ||
calcMinMax(dataSet: newElement) | ||
} | ||
|
||
public func remove(at position: Index) -> Element | ||
{ | ||
let element = self._dataSets.remove(at: position) | ||
calcMinMax() | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. shall we use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought about that. I think we should keep the way it is now for this PR. The existing There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Maybe we can rethink that in another PR though. |
||
return element | ||
} | ||
|
||
public func removeFirst() -> Element | ||
{ | ||
let element = self._dataSets.removeFirst() | ||
notifyDataChanged() | ||
return element | ||
} | ||
|
||
public func removeFirst(_ n: Int) | ||
{ | ||
self._dataSets.removeFirst(n) | ||
notifyDataChanged() | ||
} | ||
|
||
public func removeLast() -> Element | ||
{ | ||
let element = self._dataSets.removeLast() | ||
notifyDataChanged() | ||
return element | ||
} | ||
|
||
public func removeLast(_ n: Int) | ||
{ | ||
self._dataSets.removeLast(n) | ||
notifyDataChanged() | ||
} | ||
|
||
// public func removeSubrange(_ bounds: Range<Index>) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't need to call notifyDatChanged here()? how about in There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. We do because we are accessing the backing var so it's never called. In a future PR I will remove the backing var and refactor this. Currently this works the exact same way as the other add/remove methods, but are simply Swift Protocol versions (as they should be). |
||
// self.dataSets.removeSubrange(bounds) | ||
// notifyDataChanged() | ||
// } | ||
} | ||
|
||
// MARK: Swift Accessors | ||
extension ChartData | ||
{ | ||
//TODO: Reevaluate if warning is still true | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm close to finish review soon, do we handle TODO here or in future PRs? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I meant to delete it. |
||
/// 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? | ||
{ | ||
get | ||
{ | ||
guard let index = index(forLabel: label, ignoreCase: ignoreCase) else { return nil } | ||
return self[index] | ||
} | ||
} | ||
|
||
public subscript(entry: ChartDataEntry) -> Element? | ||
{ | ||
get | ||
{ | ||
guard let index = index(where: { $0.entryForXValue(entry.x, closestToY: entry.y) === entry }) else { return nil } | ||
return self[index] | ||
} | ||
} | ||
|
||
public 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 | ||
} | ||
|
||
let set = self[dataSetIndex] | ||
if !set.addEntry(e) { return } | ||
calcMinMax(entry: e, axis: set.axisDependency) | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -19,7 +19,7 @@ open class CombinedChartData: BarLineScatterCandleBubbleChartData | |
private var _candleData: CandleChartData! | ||
private var _bubbleData: BubbleChartData! | ||
|
||
public override init() | ||
public required init() | ||
{ | ||
super.init() | ||
} | ||
|
@@ -28,6 +28,11 @@ open class CombinedChartData: BarLineScatterCandleBubbleChartData | |
{ | ||
super.init(dataSets: dataSets) | ||
} | ||
|
||
public required init(arrayLiteral elements: ChartDataSetProtocol...) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. have you checked if any tricky bug or trap (like index to a wrong position) regards CombinedChartData collection conformance? CombinedChartData is a wrapper putting other data together like barData, lineData. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I made sure that all the new Swift methods/properties have the same implementations as the existing ones, so this shouldn't be an issue. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure. It will take more time, need to catch up the dataset protocol first. |
||
{ | ||
super.init(dataSets: elements) | ||
} | ||
|
||
@objc open var lineData: LineChartData! | ||
{ | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
why many become required init() now?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a requirement of
RangeReplaceableCollection
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
hmm.. My Dash API Doc does not show this to me
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
From Apple
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Found a Dash bug :)