From c8f36fe2cb29c56cf80c760fa5fca36ceed7e5c0 Mon Sep 17 00:00:00 2001 From: liuxuan30 Date: Sun, 7 Jan 2018 10:44:48 +0800 Subject: [PATCH 1/3] change to generic type declaration. fix a dead loop in @objc public convenience init(results: RLMResults?, yValueField: String) --- .../Classes/Data/RealmBarDataSet.swift | 8 +-- .../Classes/Data/RealmBaseDataSet.swift | 10 ++-- .../Classes/Data/RealmCandleDataSet.swift | 4 +- .../Classes/Data/RealmPieDataSet.swift | 2 +- .../Classes/Data/RealmRadarDataSet.swift | 58 +------------------ ChartsRealm/Supporting Files/RLMSupport.swift | 2 + 6 files changed, 15 insertions(+), 69 deletions(-) diff --git a/ChartsRealm/Classes/Data/RealmBarDataSet.swift b/ChartsRealm/Classes/Data/RealmBarDataSet.swift index b1d8fd6..21f6dfc 100644 --- a/ChartsRealm/Classes/Data/RealmBarDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmBarDataSet.swift @@ -45,7 +45,7 @@ open class RealmBarDataSet: RealmBarLineScatterCandleBubbleDataSet, IBarChartDat super.init(results: results, xValueField: xValueField, yValueField: yValueField, label: label) } - public convenience init(results: Results?, xValueField: String?, yValueField: String, stackValueField: String, label: String?) + public convenience init(results: Results?, xValueField: String?, yValueField: String, stackValueField: String, label: String?) { var converted: RLMResults? @@ -62,7 +62,7 @@ open class RealmBarDataSet: RealmBarLineScatterCandleBubbleDataSet, IBarChartDat self.init(results: results, xValueField: xValueField, yValueField: yValueField, stackValueField: stackValueField, label: "DataSet") } - public convenience init(results: Results?, xValueField: String?, yValueField: String, stackValueField: String) + public convenience init(results: Results?, xValueField: String?, yValueField: String, stackValueField: String) { var converted: RLMResults? @@ -79,7 +79,7 @@ open class RealmBarDataSet: RealmBarLineScatterCandleBubbleDataSet, IBarChartDat self.init(results: results, xValueField: nil, yValueField: yValueField, stackValueField: stackValueField, label: label) } - public convenience init(results: Results?, yValueField: String, stackValueField: String, label: String) + public convenience init(results: Results?, yValueField: String, stackValueField: String, label: String) { var converted: RLMResults? @@ -96,7 +96,7 @@ open class RealmBarDataSet: RealmBarLineScatterCandleBubbleDataSet, IBarChartDat self.init(results: results, xValueField: nil, yValueField: yValueField, stackValueField: stackValueField) } - public convenience init(results: Results?, yValueField: String, stackValueField: String) + public convenience init(results: Results?, yValueField: String, stackValueField: String) { var converted: RLMResults? diff --git a/ChartsRealm/Classes/Data/RealmBaseDataSet.swift b/ChartsRealm/Classes/Data/RealmBaseDataSet.swift index 4d2c834..c55e90f 100644 --- a/ChartsRealm/Classes/Data/RealmBaseDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmBaseDataSet.swift @@ -67,7 +67,7 @@ open class RealmBaseDataSet: ChartBaseDataSet initialize() } - public convenience init(results: Results?, xValueField: String?, yValueField: String, label: String?) + public convenience init(results: Results?, xValueField: String?, yValueField: String, label: String?) { var converted: RLMResults? @@ -84,7 +84,7 @@ open class RealmBaseDataSet: ChartBaseDataSet self.init(results: results, xValueField: nil, yValueField: yValueField, label: label) } - public convenience init(results: Results?, yValueField: String, label: String?) + public convenience init(results: Results?, yValueField: String, label: String?) { var converted: RLMResults? @@ -101,7 +101,7 @@ open class RealmBaseDataSet: ChartBaseDataSet self.init(results: results, xValueField: xValueField, yValueField: yValueField, label: "DataSet") } - public convenience init(results: Results?, xValueField: String?, yValueField: String) + public convenience init(results: Results?, xValueField: String?, yValueField: String) { var converted: RLMResults? @@ -115,10 +115,10 @@ open class RealmBaseDataSet: ChartBaseDataSet @objc public convenience init(results: RLMResults?, yValueField: String) { - self.init(results: results, yValueField: yValueField) + self.init(results: results, yValueField: yValueField, label: nil) } - public convenience init(results: Results?, yValueField: String) + public convenience init(results: Results?, yValueField: String) { var converted: RLMResults? diff --git a/ChartsRealm/Classes/Data/RealmCandleDataSet.swift b/ChartsRealm/Classes/Data/RealmCandleDataSet.swift index 72ae136..46087c3 100644 --- a/ChartsRealm/Classes/Data/RealmCandleDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmCandleDataSet.swift @@ -38,7 +38,7 @@ open class RealmCandleDataSet: RealmLineScatterCandleRadarDataSet, ICandleChartD super.init(results: results, xValueField: xValueField, yValueField: "", label: label) } - public convenience init(results: Results?, xValueField: String, highField: String, lowField: String, openField: String, closeField: String, label: String?) + public convenience init(results: Results?, xValueField: String, highField: String, lowField: String, openField: String, closeField: String, label: String?) { var converted: RLMResults? @@ -55,7 +55,7 @@ open class RealmCandleDataSet: RealmLineScatterCandleRadarDataSet, ICandleChartD self.init(results: results, xValueField: xValueField, highField: highField, lowField: lowField, openField: openField, closeField: closeField, label: "DataSet") } - public convenience init(results: Results?, xValueField: String, highField: String, lowField: String, openField: String, closeField: String) + public convenience init(results: Results?, xValueField: String, highField: String, lowField: String, openField: String, closeField: String) { var converted: RLMResults? diff --git a/ChartsRealm/Classes/Data/RealmPieDataSet.swift b/ChartsRealm/Classes/Data/RealmPieDataSet.swift index 0ca7b01..f8d4812 100644 --- a/ChartsRealm/Classes/Data/RealmPieDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmPieDataSet.swift @@ -36,7 +36,7 @@ open class RealmPieDataSet: RealmBaseDataSet, IPieChartDataSet super.init(results: results, xValueField: nil, yValueField: yValueField, label: nil) } - public convenience init(results: Results?, yValueField: String, labelField: String?) + public convenience init(results: Results?, yValueField: String, labelField: String?) { var converted: RLMResults? diff --git a/ChartsRealm/Classes/Data/RealmRadarDataSet.swift b/ChartsRealm/Classes/Data/RealmRadarDataSet.swift index bbf1f89..fc06bbc 100644 --- a/ChartsRealm/Classes/Data/RealmRadarDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmRadarDataSet.swift @@ -22,63 +22,7 @@ open class RealmRadarDataSet: RealmLineRadarDataSet, IRadarChartDataSet { self.valueFont = NSUIFont.systemFont(ofSize: 13.0) } - - public required init() - { - super.init() - } - - public init(results: RLMResults?, yValueField: String, label: String?) - { - super.init(results: results, xValueField: nil, yValueField: yValueField, label: label) - } - - public convenience init(results: Results?, yValueField: String, label: String?) - { - var converted: RLMResults? - - if results != nil - { - converted = ObjectiveCSupport.convert(object: results!) as? RLMResults - } - - self.init(results: converted, yValueField: yValueField, label: label) - } - - public convenience init(results: RLMResults?, yValueField: String) - { - self.init(results: results, yValueField: yValueField, label: "DataSet") - } - - public convenience init(results: Results?, yValueField: String) - { - var converted: RLMResults? - - if results != nil - { - converted = ObjectiveCSupport.convert(object: results!) as? RLMResults - } - - self.init(results: converted, yValueField: yValueField) - } - - public init(realm: RLMRealm?, modelName: String, resultsWhere: String, yValueField: String, label: String?) - { - super.init(realm: realm, modelName: modelName, resultsWhere: resultsWhere, xValueField: nil, yValueField: yValueField, label: label) - } - - public convenience init(realm: Realm?, modelName: String, resultsWhere: String, yValueField: String, label: String?) - { - var converted: RLMRealm? - - if realm != nil - { - converted = ObjectiveCSupport.convert(object: realm!) - } - - self.init(realm: converted, modelName: modelName, resultsWhere: resultsWhere, yValueField: yValueField, label: label) - } - + // MARK: - Data functions and accessors internal override func buildEntryFromResultObject(_ object: RLMObject, x: Double) -> ChartDataEntry diff --git a/ChartsRealm/Supporting Files/RLMSupport.swift b/ChartsRealm/Supporting Files/RLMSupport.swift index efc57d3..4c1b576 100644 --- a/ChartsRealm/Supporting Files/RLMSupport.swift +++ b/ChartsRealm/Supporting Files/RLMSupport.swift @@ -15,6 +15,7 @@ // limitations under the License. // //////////////////////////////////////////////////////////////////////////// + import Realm extension RLMRealm { @@ -85,6 +86,7 @@ extension RLMCollection { } // MARK: - Sync-related + extension RLMSyncManager { public static var shared: RLMSyncManager { return __shared() From b17da681e8e9195a8d624ec9667c8606756caac1 Mon Sep 17 00:00:00 2001 From: liuxuan30 Date: Sun, 7 Jan 2018 12:23:19 +0800 Subject: [PATCH 2/3] fix a crash if results is always nil, buildCache() will fail and _cache is empty --- ChartsRealm/Classes/Data/RealmBaseDataSet.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/ChartsRealm/Classes/Data/RealmBaseDataSet.swift b/ChartsRealm/Classes/Data/RealmBaseDataSet.swift index c55e90f..c8358a9 100644 --- a/ChartsRealm/Classes/Data/RealmBaseDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmBaseDataSet.swift @@ -331,6 +331,7 @@ open class RealmBaseDataSet: ChartBaseDataSet { buildCache() } + guard _cache.count > 0 else { return nil } return _cache[i] } From f6e396e3e03f4d34fdb26970eb350a30e2fdc4e9 Mon Sep 17 00:00:00 2001 From: liuxuan30 Date: Thu, 18 Jan 2018 15:32:35 +0800 Subject: [PATCH 3/3] Make ChartsRealm great again using RLMObjectBase as base type, and later cast to RLMObject or Object --- .../Classes/Data/RealmBarDataSet.swift | 31 +- .../Classes/Data/RealmBaseDataSet.swift | 326 +++++++++--------- .../Classes/Data/RealmBubbleDataSet.swift | 12 +- .../Classes/Data/RealmCandleDataSet.swift | 17 +- .../Classes/Data/RealmPieDataSet.swift | 20 +- .../Classes/Data/RealmRadarDataSet.swift | 11 +- 6 files changed, 247 insertions(+), 170 deletions(-) diff --git a/ChartsRealm/Classes/Data/RealmBarDataSet.swift b/ChartsRealm/Classes/Data/RealmBarDataSet.swift index 21f6dfc..37e1e0c 100644 --- a/ChartsRealm/Classes/Data/RealmBarDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmBarDataSet.swift @@ -197,9 +197,18 @@ open class RealmBarDataSet: RealmBarLineScatterCandleBubbleDataSet, IBarChartDat /// is calculated from the Entries that are added to the DataSet fileprivate var _stackSize = 1 - internal override func buildEntryFromResultObject(_ object: RLMObject, x: Double) -> ChartDataEntry + internal override func buildEntryFromResultObject(_ object: RLMObjectBase, x: Double) -> ChartDataEntry { - let value = object[_yValueField!] + var value: Any? + if let object = object as? RLMObject + { + value = object[_yValueField!] + } + else + { + value = (object as! Object)[_yValueField!] + } + let entry: BarChartDataEntry if let array = value as? RLMArray @@ -209,11 +218,25 @@ open class RealmBarDataSet: RealmBarLineScatterCandleBubbleDataSet, IBarChartDat { values.append(val[_stackValueField!] as! Double) } - entry = BarChartDataEntry(x: _xValueField == nil ? x : object[_xValueField!] as! Double, yValues: values) + if let object = object as? RLMObject + { + entry = BarChartDataEntry(x: _xValueField == nil ? x : object[_xValueField!] as! Double, yValues: values) + } + else + { + entry = BarChartDataEntry(x: _xValueField == nil ? x : (object as! Object)[_xValueField!] as! Double, yValues: values) + } } else { - entry = BarChartDataEntry(x: _xValueField == nil ? x : object[_xValueField!] as! Double, y: value as! Double) + if let object = object as? RLMObject + { + entry = BarChartDataEntry(x: _xValueField == nil ? x : object[_xValueField!] as! Double, y: value as! Double) + } + else + { + entry = BarChartDataEntry(x: _xValueField == nil ? x : (object as! Object)[_xValueField!] as! Double, y: value as! Double) + } } return entry diff --git a/ChartsRealm/Classes/Data/RealmBaseDataSet.swift b/ChartsRealm/Classes/Data/RealmBaseDataSet.swift index c8358a9..bfbaf50 100644 --- a/ChartsRealm/Classes/Data/RealmBaseDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmBaseDataSet.swift @@ -21,272 +21,284 @@ open class RealmBaseDataSet: ChartBaseDataSet { fatalError("RealmBaseDataSet is an abstract class, you must inherit from it. Also please do not call super.initialize().") } - + public required init() { super.init() - + // default color colors.append(NSUIColor(red: 140.0/255.0, green: 234.0/255.0, blue: 255.0/255.0, alpha: 1.0)) - + initialize() } - + public override init(label: String?) { super.init() - + // default color colors.append(NSUIColor(red: 140.0/255.0, green: 234.0/255.0, blue: 255.0/255.0, alpha: 1.0)) - + self.label = label - + initialize() } - + + // MARK: Realm for Objective-C + @objc public init(results: RLMResults?, xValueField: String?, yValueField: String, label: String?) { super.init() - + // default color colors.append(NSUIColor(red: 140.0/255.0, green: 234.0/255.0, blue: 255.0/255.0, alpha: 1.0)) - + self.label = label - - _results = results + + _results = results as? RLMResults _yValueField = yValueField _xValueField = xValueField - + if _xValueField != nil { _results = _results?.sortedResults(usingKeyPath: _xValueField!, ascending: true) } - + notifyDataSetChanged() - + initialize() } - + + @objc public convenience init(results: RLMResults?, yValueField: String, label: String?) + { + self.init(results: results, xValueField: nil, yValueField: yValueField, label: label) + } + + @objc public convenience init(results: RLMResults?, xValueField: String?, yValueField: String) + { + self.init(results: results, xValueField: xValueField, yValueField: yValueField, label: "DataSet") + } + + @objc public convenience init(results: RLMResults?, yValueField: String) + { + self.init(results: results, yValueField: yValueField, label: nil) + } + + // MARK: RealmSwift + public convenience init(results: Results?, xValueField: String?, yValueField: String, label: String?) { var converted: RLMResults? - + if results != nil { converted = ObjectiveCSupport.convert(object: results!) as? RLMResults } - + self.init(results: converted, xValueField: xValueField, yValueField: yValueField, label: label) } - - @objc public convenience init(results: RLMResults?, yValueField: String, label: String?) - { - self.init(results: results, xValueField: nil, yValueField: yValueField, label: label) - } - + public convenience init(results: Results?, yValueField: String, label: String?) { var converted: RLMResults? - + if results != nil { converted = ObjectiveCSupport.convert(object: results!) as? RLMResults } - + self.init(results: converted, yValueField: yValueField, label: label) } - - @objc public convenience init(results: RLMResults?, xValueField: String?, yValueField: String) - { - self.init(results: results, xValueField: xValueField, yValueField: yValueField, label: "DataSet") - } - + public convenience init(results: Results?, xValueField: String?, yValueField: String) { var converted: RLMResults? - + if results != nil { converted = ObjectiveCSupport.convert(object: results!) as? RLMResults } - + self.init(results: converted, xValueField: xValueField, yValueField: yValueField) } - - @objc public convenience init(results: RLMResults?, yValueField: String) - { - self.init(results: results, yValueField: yValueField, label: nil) - } - + public convenience init(results: Results?, yValueField: String) { var converted: RLMResults? - + if results != nil { converted = ObjectiveCSupport.convert(object: results!) as? RLMResults } - + self.init(results: converted, yValueField: yValueField) } - + @objc public init(realm: RLMRealm?, modelName: String, resultsWhere: String, xValueField: String?, yValueField: String, label: String?) { super.init() - + // default color colors.append(NSUIColor(red: 140.0/255.0, green: 234.0/255.0, blue: 255.0/255.0, alpha: 1.0)) - + self.label = label - + _yValueField = yValueField _xValueField = xValueField - + if realm != nil { loadResults(realm: realm!, modelName: modelName) } - + initialize() } - + public convenience init(realm: Realm?, modelName: String, resultsWhere: String, xValueField: String?, yValueField: String, label: String?) { var converted: RLMRealm? - + if realm != nil { converted = ObjectiveCSupport.convert(object: realm!) } - + self.init(realm: converted, modelName: modelName, resultsWhere: resultsWhere, xValueField: xValueField, yValueField: yValueField, label: label) } - + @objc public convenience init(realm: RLMRealm?, modelName: String, resultsWhere: String, yValueField: String, label: String?) { self.init(realm: realm, modelName: modelName, resultsWhere: resultsWhere, xValueField: nil, yValueField: yValueField, label: label) } - + public convenience init(realm: Realm?, modelName: String, resultsWhere: String, yValueField: String, label: String?) { var converted: RLMRealm? - + if realm != nil { converted = ObjectiveCSupport.convert(object: realm!) } - + self.init(realm: converted, modelName: modelName, resultsWhere: resultsWhere, yValueField: yValueField, label: label) } - + @objc open func loadResults(realm: RLMRealm, modelName: String) { loadResults(realm: realm, modelName: modelName, predicate: nil) } - + @objc open func loadResults(realm: RLMRealm, modelName: String, predicate: NSPredicate?) { if predicate == nil { - _results = realm.allObjects(modelName) + _results = realm.allObjects(modelName) as? RLMResults } else { - _results = realm.objects(modelName, with: predicate!) + _results = realm.objects(modelName, with: predicate!) as? RLMResults } - + if _xValueField != nil { _results = _results?.sortedResults(usingKeyPath: _xValueField!, ascending: true) } - + notifyDataSetChanged() } - + @nonobjc open func loadResults(realm: Realm, modelName: String) { loadResults(realm: ObjectiveCSupport.convert(object: realm), modelName: modelName) } - + @nonobjc open func loadResults(realm: Realm, modelName: String, predicate: NSPredicate?) { loadResults(realm: ObjectiveCSupport.convert(object: realm), modelName: modelName, predicate: predicate) } - + // MARK: - Data functions and accessors - - @objc internal var _results: RLMResults? + + @objc internal var _results: RLMResults? @objc internal var _yValueField: String? @objc internal var _xValueField: String? @objc internal var _cache = [ChartDataEntry]() - + @objc internal var _yMax: Double = -Double.greatestFiniteMagnitude @objc internal var _yMin: Double = Double.greatestFiniteMagnitude - + @objc internal var _xMax: Double = -Double.greatestFiniteMagnitude @objc internal var _xMin: Double = Double.greatestFiniteMagnitude - + /// Makes sure that the cache is populated for the specified range @objc internal func buildCache() { guard let results = _results else { return } - + _cache.removeAll() _cache.reserveCapacity(Int(results.count)) - + var xValue: Double = 0.0 - + var iterator = NSFastEnumerationIterator(results) while let e = iterator.next() { - _cache.append(buildEntryFromResultObject(e as! RLMObject, x: xValue)) + _cache.append(buildEntryFromResultObject(e as! RLMObjectBase, x: xValue)) xValue += 1.0 } } - - @objc internal func buildEntryFromResultObject(_ object: RLMObject, x: Double) -> ChartDataEntry + + @objc internal func buildEntryFromResultObject(_ object: RLMObjectBase, x: Double) -> ChartDataEntry { - let entry = ChartDataEntry(x: _xValueField == nil ? x : object[_xValueField!] as! Double, y: object[_yValueField!] as! Double) - + let entry: ChartDataEntry + if let object = object as? RLMObject + { + entry = ChartDataEntry(x: _xValueField == nil ? x : object[_xValueField!] as! Double, y: object[_yValueField!] as! Double) + } + else + { + entry = ChartDataEntry(x: _xValueField == nil ? x : (object as! Object)[_xValueField!] as! Double, y: (object as! Object)[_yValueField!] as! Double) + } + return entry } - + /// Makes sure that the cache is populated for the specified range @objc internal func clearCache() { _cache.removeAll() } - + /// Use this method to tell the data set that the underlying data has changed open override func notifyDataSetChanged() { buildCache() calcMinMax() } - + open override func calcMinMax() { if _cache.count == 0 { return } - + _yMax = -Double.greatestFiniteMagnitude _yMin = Double.greatestFiniteMagnitude _xMax = -Double.greatestFiniteMagnitude _xMin = Double.greatestFiniteMagnitude - + for e in _cache { calcMinMax(entry: e) } } - - /// Updates the min and max x and y value of this DataSet based on the given Entry. - /// - /// - parameter e: + + /// Updates the min and max x and y value of this DataSet based on the given Entry. + /// + /// - parameter e: @objc internal func calcMinMax(entry e: ChartDataEntry) { if e.y < _yMin @@ -309,19 +321,19 @@ open class RealmBaseDataSet: ChartBaseDataSet /// - returns: The minimum y-value this DataSet holds open override var yMin: Double { return _yMin } - + /// - returns: The maximum y-value this DataSet holds open override var yMax: Double { return _yMax } - + /// - returns: The minimum x-value this DataSet holds open override var xMin: Double { return _xMin } - + /// - returns: The maximum x-value this DataSet holds open override var xMax: Double { return _xMax } - + /// - returns: The number of y-values this DataSet represents open override var entryCount: Int { return Int(_results?.count ?? 0) } - + /// - returns: The entry object found at the given index (not x-value!) /// - throws: out of bounds /// if `i` is out of bounds, it may throw an out-of-bounds exception @@ -334,7 +346,7 @@ open class RealmBaseDataSet: ChartBaseDataSet guard _cache.count > 0 else { return nil } return _cache[i] } - + /// - returns: The first Entry object found at the given x-value with binary search. /// If the no Entry at the specified x-value is found, this method returns the Entry at the closest x-value according to the rounding. /// nil if no Entry object at that x-value. @@ -353,7 +365,7 @@ open class RealmBaseDataSet: ChartBaseDataSet } return nil } - + /// - returns: The first Entry object found at the given x-value with binary search. /// If the no Entry at the specified x-value is found, this method returns the Entry at the closest x-value. /// nil if no Entry object at that x-value. @@ -365,46 +377,46 @@ open class RealmBaseDataSet: ChartBaseDataSet { return entryForXValue(xValue, closestToY: y, rounding: .closest) } - + /// - returns: All Entry objects found at the given x-value with binary search. /// An empty array if no Entry object at that x-value. open override func entriesForXValue(_ xValue: Double) -> [ChartDataEntry] { /*var entries = [ChartDataEntry]() - - guard let results = _results else { return entries } - - if _xValueField != nil - { - let foundObjects = results.objectsWithPredicate( - NSPredicate(format: "%K == %f", _xValueField!, x) - ) - - for e in foundObjects - { - entries.append(buildEntryFromResultObject(e as! RLMObject, x: x)) - } - } - - return entries*/ - + + guard let results = _results else { return entries } + + if _xValueField != nil + { + let foundObjects = results.objectsWithPredicate( + NSPredicate(format: "%K == %f", _xValueField!, x) + ) + + for e in foundObjects + { + entries.append(buildEntryFromResultObject(e as! RLMObject, x: x)) + } + } + + return entries*/ + var entries = [ChartDataEntry]() - + var low = 0 var high = _cache.count - 1 - + while low <= high { var m = (high + low) / 2 var entry = _cache[m] - + if xValue == entry.x { while m > 0 && _cache[m - 1].x == xValue { m -= 1 } - + high = _cache.count while m < high { @@ -417,10 +429,10 @@ open class RealmBaseDataSet: ChartBaseDataSet { break } - + m += 1 } - + break } else @@ -435,10 +447,10 @@ open class RealmBaseDataSet: ChartBaseDataSet } } } - + return entries } - + /// - returns: The array-index of the specified entry. /// If the no Entry at the specified x-value is found, this method returns the index of the Entry at the closest x-value according to the rounding. /// @@ -451,27 +463,27 @@ open class RealmBaseDataSet: ChartBaseDataSet rounding: ChartDataSetRounding) -> Int { /*guard let results = _results else { return -1 } - - let foundIndex = results.indexOfObjectWithPredicate( - NSPredicate(format: "%K == %f", _xValueField!, x) - ) - - // TODO: Figure out a way to quickly find the closest index - - return Int(foundIndex)*/ - + + let foundIndex = results.indexOfObjectWithPredicate( + NSPredicate(format: "%K == %f", _xValueField!, x) + ) + + // TODO: Figure out a way to quickly find the closest index + + return Int(foundIndex)*/ + var low = 0 var high = _cache.count - 1 var closest = high - + while low < high { let m = (low + high) / 2 - + let d1 = _cache[m].x - xValue let d2 = _cache[m + 1].x - xValue let ad1 = abs(d1), ad2 = abs(d2) - + if ad2 < ad1 { // [m + 1] is closer to xValue @@ -487,7 +499,7 @@ open class RealmBaseDataSet: ChartBaseDataSet else { // We have multiple sequential x-value with same distance - + if d1 >= 0.0 { // Search in a lower place @@ -499,14 +511,14 @@ open class RealmBaseDataSet: ChartBaseDataSet low = m + 1 } } - + closest = high } - + if closest != -1 { let closestXValue = _cache[closest].x - + if rounding == .up { // If rounding up, and found x-value is lower than specified x, and we can go upper... @@ -523,7 +535,7 @@ open class RealmBaseDataSet: ChartBaseDataSet closest -= 1 } } - + // Search by closest to y-value if !yValue.isNaN { @@ -531,17 +543,17 @@ open class RealmBaseDataSet: ChartBaseDataSet { closest -= 1 } - + var closestYValue = _cache[closest].y var closestYIndex = closest - + while true { closest += 1 if closest >= _cache.count { break } - + let value = _cache[closest] - + if value.x != closestXValue { break } if abs(value.y - yValue) < abs(closestYValue - yValue) { @@ -549,14 +561,14 @@ open class RealmBaseDataSet: ChartBaseDataSet closestYIndex = closest } } - + closest = closestYIndex } } - + return closest } - + /// - returns: The array-index of the specified entry /// /// - parameter e: the entry to search for @@ -569,28 +581,28 @@ open class RealmBaseDataSet: ChartBaseDataSet return i } } - + return -1 } - + /// Not supported on Realm datasets open override func addEntry(_ e: ChartDataEntry) -> Bool { return false } - + /// Not supported on Realm datasets open override func addEntryOrdered(_ e: ChartDataEntry) -> Bool { return false } - + /// Not supported on Realm datasets open override func removeEntry(_ entry: ChartDataEntry) -> Bool { return false } - + /// Checks if this DataSet contains the specified Entry. /// - returns: `true` if contains the entry, `false` ifnot. open override func contains(_ e: ChartDataEntry) -> Bool @@ -602,34 +614,34 @@ open class RealmBaseDataSet: ChartBaseDataSet return true } } - + return false } - + /// - returns: The fieldname that represents the "y-values" in the realm-data. @objc open var yValueField: String? - { + { get { return _yValueField } } - + /// - returns: The fieldname that represents the "x-values" in the realm-data. @objc open var xValueField: String? - { + { get { return _xValueField } } - + // MARK: - NSCopying - + open override func copyWithZone(_ zone: NSZone?) -> AnyObject { let copy = super.copyWithZone(zone) as! RealmBaseDataSet - + copy._results = _results copy._yValueField = _yValueField copy._xValueField = _xValueField @@ -637,7 +649,7 @@ open class RealmBaseDataSet: ChartBaseDataSet copy._yMin = _yMin copy._xMax = _xMax copy._xMin = _xMin - + return copy } } diff --git a/ChartsRealm/Classes/Data/RealmBubbleDataSet.swift b/ChartsRealm/Classes/Data/RealmBubbleDataSet.swift index 4ba772f..0bd0c25 100644 --- a/ChartsRealm/Classes/Data/RealmBubbleDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmBubbleDataSet.swift @@ -92,9 +92,17 @@ open class RealmBubbleDataSet: RealmBarLineScatterCandleBubbleDataSet, IBubbleCh @objc open var normalizeSizeEnabled: Bool = true open var isNormalizeSizeEnabled: Bool { return normalizeSizeEnabled } - internal override func buildEntryFromResultObject(_ object: RLMObject, x: Double) -> ChartDataEntry + internal override func buildEntryFromResultObject(_ object: RLMObjectBase, x: Double) -> ChartDataEntry { - let entry = BubbleChartDataEntry(x: _xValueField == nil ? x : object[_xValueField!] as! Double, y: object[_yValueField!] as! Double, size: object[_sizeField!] as! CGFloat) + let entry: BubbleChartDataEntry + if let object = object as? RLMObject + { + entry = BubbleChartDataEntry(x: _xValueField == nil ? x : object[_xValueField!] as! Double, y: object[_yValueField!] as! Double, size: object[_sizeField!] as! CGFloat) + } + else + { + entry = BubbleChartDataEntry(x: _xValueField == nil ? x : (object as! Object)[_xValueField!] as! Double, y: (object as! Object)[_yValueField!] as! Double, size: (object as! Object)[_sizeField!] as! CGFloat) + } return entry } diff --git a/ChartsRealm/Classes/Data/RealmCandleDataSet.swift b/ChartsRealm/Classes/Data/RealmCandleDataSet.swift index 46087c3..617e0fc 100644 --- a/ChartsRealm/Classes/Data/RealmCandleDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmCandleDataSet.swift @@ -96,14 +96,27 @@ open class RealmCandleDataSet: RealmLineScatterCandleRadarDataSet, ICandleChartD @objc internal var _openField: String? @objc internal var _closeField: String? - internal override func buildEntryFromResultObject(_ object: RLMObject, x: Double) -> ChartDataEntry + internal override func buildEntryFromResultObject(_ object: RLMObjectBase, x: Double) -> ChartDataEntry { - let entry = CandleChartDataEntry( + let entry: CandleChartDataEntry + if let object = object as? RLMObject + { + entry = CandleChartDataEntry( x: _xValueField == nil ? x : object[_xValueField!] as! Double, shadowH: object[_highField!] as! Double, shadowL: object[_lowField!] as! Double, open: object[_openField!] as! Double, close: object[_closeField!] as! Double) + } + else + { + entry = CandleChartDataEntry( + x: _xValueField == nil ? x : (object as! Object)[_xValueField!] as! Double, + shadowH: (object as! Object)[_highField!] as! Double, + shadowL: (object as! Object)[_lowField!] as! Double, + open: (object as! Object)[_openField!] as! Double, + close: (object as! Object)[_closeField!] as! Double) + } return entry } diff --git a/ChartsRealm/Classes/Data/RealmPieDataSet.swift b/ChartsRealm/Classes/Data/RealmPieDataSet.swift index f8d4812..5598f42 100644 --- a/ChartsRealm/Classes/Data/RealmPieDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmPieDataSet.swift @@ -52,15 +52,29 @@ open class RealmPieDataSet: RealmBaseDataSet, IPieChartDataSet @objc internal var _labelField: String? - internal override func buildEntryFromResultObject(_ object: RLMObject, x: Double) -> ChartDataEntry + internal override func buildEntryFromResultObject(_ object: RLMObjectBase, x: Double) -> ChartDataEntry { if _labelField == nil { - return PieChartDataEntry(value: object[_yValueField!] as! Double) + if let object = object as? RLMObject + { + return PieChartDataEntry(value: object[_yValueField!] as! Double) + } + else + { + return PieChartDataEntry(value: (object as! Object)[_yValueField!] as! Double) + } } else { - return PieChartDataEntry(value: object[_yValueField!] as! Double, label: object[_labelField!] as? String) + if let object = object as? RLMObject + { + return PieChartDataEntry(value: object[_yValueField!] as! Double, label: object[_labelField!] as? String) + } + else + { + return PieChartDataEntry(value: (object as! Object)[_yValueField!] as! Double, label: (object as! Object)[_labelField!] as? String) + } } } diff --git a/ChartsRealm/Classes/Data/RealmRadarDataSet.swift b/ChartsRealm/Classes/Data/RealmRadarDataSet.swift index fc06bbc..cd5ab8f 100644 --- a/ChartsRealm/Classes/Data/RealmRadarDataSet.swift +++ b/ChartsRealm/Classes/Data/RealmRadarDataSet.swift @@ -25,9 +25,16 @@ open class RealmRadarDataSet: RealmLineRadarDataSet, IRadarChartDataSet // MARK: - Data functions and accessors - internal override func buildEntryFromResultObject(_ object: RLMObject, x: Double) -> ChartDataEntry + internal override func buildEntryFromResultObject(_ object: RLMObjectBase, x: Double) -> ChartDataEntry { - return RadarChartDataEntry(value: object[_yValueField!] as! Double) + if let object = object as? RLMObject + { + return RadarChartDataEntry(value: object[_yValueField!] as! Double) + } + else + { + return RadarChartDataEntry(value: (object as! Object)[_yValueField!] as! Double) + } } // MARK: - Styling functions and accessors