1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
//
// BarLineScatterCandleBubbleRenderer.swift
// Charts
//
// Copyright 2015 Daniel Cohen Gindi & Philipp Jahoda
// A port of MPAndroidChart for iOS
// Licensed under Apache License 2.0
//
// https://github.com/danielgindi/Charts
//
import Foundation
import CoreGraphics
@objc(BarLineScatterCandleBubbleChartRenderer)
open class BarLineScatterCandleBubbleRenderer: DataRenderer
{
internal var _xBounds = XBounds() // Reusable XBounds object
public override init(animator: Animator, viewPortHandler: ViewPortHandler)
{
super.init(animator: animator, viewPortHandler: viewPortHandler)
}
/// Checks if the provided entry object is in bounds for drawing considering the current animation phase.
internal func isInBoundsX(entry e: ChartDataEntry, dataSet: IBarLineScatterCandleBubbleChartDataSet) -> Bool
{
let entryIndex = dataSet.entryIndex(entry: e)
return Double(entryIndex) < Double(dataSet.entryCount) * animator.phaseX
}
/// Calculates and returns the x-bounds for the given DataSet in terms of index in their values array.
/// This includes minimum and maximum visible x, as well as range.
internal func xBounds(chart: BarLineScatterCandleBubbleChartDataProvider,
dataSet: IBarLineScatterCandleBubbleChartDataSet,
animator: Animator?) -> XBounds
{
return XBounds(chart: chart, dataSet: dataSet, animator: animator)
}
/// - Returns: `true` if the DataSet values should be drawn, `false` if not.
internal func shouldDrawValues(forDataSet set: IChartDataSet) -> Bool
{
return set.isVisible && (set.isDrawValuesEnabled || set.isDrawIconsEnabled)
}
/// Class representing the bounds of the current viewport in terms of indices in the values array of a DataSet.
open class XBounds
{
/// minimum visible entry index
open var min: Int = 0
/// maximum visible entry index
open var max: Int = 0
/// range of visible entry indices
open var range: Int = 0
public init()
{
}
public init(chart: BarLineScatterCandleBubbleChartDataProvider,
dataSet: IBarLineScatterCandleBubbleChartDataSet,
animator: Animator?)
{
self.set(chart: chart, dataSet: dataSet, animator: animator)
}
/// Calculates the minimum and maximum x values as well as the range between them.
open func set(chart: BarLineScatterCandleBubbleChartDataProvider,
dataSet: IBarLineScatterCandleBubbleChartDataSet,
animator: Animator?)
{
let phaseX = Swift.max(0.0, Swift.min(1.0, animator?.phaseX ?? 1.0))
let low = chart.lowestVisibleX
let high = chart.highestVisibleX
let entryFrom = dataSet.entryForXValue(low, closestToY: .nan, rounding: .down)
let entryTo = dataSet.entryForXValue(high, closestToY: .nan, rounding: .up)
self.min = entryFrom == nil ? 0 : dataSet.entryIndex(entry: entryFrom!)
self.max = entryTo == nil ? 0 : dataSet.entryIndex(entry: entryTo!)
range = Int(Double(self.max - self.min) * phaseX)
}
}
}
extension BarLineScatterCandleBubbleRenderer.XBounds: RangeExpression {
public func relative<C>(to collection: C) -> Swift.Range<Int>
where C : Collection, Bound == C.Index
{
return Swift.Range<Int>(min...min + range)
}
public func contains(_ element: Int) -> Bool {
return (min...min + range).contains(element)
}
}
extension BarLineScatterCandleBubbleRenderer.XBounds: Sequence {
public struct Iterator: IteratorProtocol {
private var iterator: IndexingIterator<ClosedRange<Int>>
fileprivate init(min: Int, max: Int) {
self.iterator = (min...max).makeIterator()
}
public mutating func next() -> Int? {
return self.iterator.next()
}
}
public func makeIterator() -> Iterator {
return Iterator(min: self.min, max: self.max)
}
}