USB-Meter / USB Meter / Model / ChartContext.swift
Newer Older
127 lines | 3.31kb
Bogdan Timofte authored 2 weeks ago
1
//
2
//  ChartContext.swift
3
//  USB Meter
4
//
5
//  Created by Bogdan Timofte on 14/04/2020.
6
//  Copyright © 2020 Bogdan Timofte. All rights reserved.
7
//
8

            
9
import CoreGraphics
10
import SwiftUI
11

            
12
class ChartContext {
13
    private var rect : CGRect?
14
    private var pad: CGFloat = 0
15

            
16
    var isValid: Bool {
17
        get {
18
            return rect != nil && rect!.width > 0 && rect!.height > 0
19
        }
20
    }
21

            
22
    var size: CGSize {
23
        get {
24
            guard rect != nil else {
25
                track("Invalid Context")
Bogdan Timofte authored 2 weeks ago
26
                return .zero
Bogdan Timofte authored 2 weeks ago
27
            }
28
            return rect!.size
29
        }
30
    }
31

            
32
    var origin: CGPoint {
33
        get {
34
            guard rect != nil else {
35
                track("Invalid Context")
Bogdan Timofte authored 2 weeks ago
36
                return .zero
Bogdan Timofte authored 2 weeks ago
37
            }
38
            return rect!.origin
39
        }
40
    }
41

            
42
    var minValue: Double {
43
        return rect == nil ? .nan : Double(rect!.minY)
44
    }
45

            
46
    var maxValue: Double {
47
        get {
48
            return rect == nil ? .nan : Double(rect!.maxY)
49
        }
50
    }
51

            
52
    func reset() {
53
        rect = nil
Bogdan Timofte authored 2 weeks ago
54
        pad = 0
Bogdan Timofte authored 2 weeks ago
55
    }
56
    func include( point: CGPoint )  {
57
        if rect == nil {
58
            rect = CGRect(origin: point, size: .zero)
59
            padding()
60
        } else {
61
            rect = rect!.union(CGRect(origin: point, size: .zero))
62
            padding()
63
        }
64
    }
65

            
66
    func padding() {
67
        guard rect != nil else {
68
            track("Invalid Context")
69
            pad = 0
Bogdan Timofte authored 2 weeks ago
70
            return
Bogdan Timofte authored 2 weeks ago
71
        }
72
        pad = rect!.size.height * Constants.chartUnderscan
73
    }
Bogdan Timofte authored 2 weeks ago
74

            
75
    func ensureMinimumSize(width minimumWidth: CGFloat = 0, height minimumHeight: CGFloat = 0) {
76
        guard var rect else { return }
77

            
78
        if rect.width < minimumWidth {
79
            let delta = (minimumWidth - rect.width) / 2
80
            rect = rect.insetBy(dx: -delta, dy: 0)
81
        }
82

            
83
        if rect.height < minimumHeight {
84
            let delta = (minimumHeight - rect.height) / 2
85
            rect = rect.insetBy(dx: 0, dy: -delta)
86
        }
87

            
88
        self.rect = rect
89
        padding()
90
    }
Bogdan Timofte authored a week ago
91

            
92
    func setBounds(xMin: CGFloat, xMax: CGFloat, yMin: CGFloat, yMax: CGFloat) {
93
        rect = CGRect(
94
            x: min(xMin, xMax),
95
            y: min(yMin, yMax),
96
            width: abs(xMax - xMin),
97
            height: max(abs(yMax - yMin), 0.1)
98
        )
99
        padding()
100
    }
Bogdan Timofte authored 2 weeks ago
101

            
102
    func yAxisLabel( for itemNo: Int, of items: Int ) -> Double {
103
        let labelSpace = Double(rect!.height) / Double(items - 1)
104
        let labelRelativeValue = labelSpace * Double(itemNo - 1)
105
        return minValue + labelRelativeValue
106
    }
107

            
108
    // MARK: Conversii dubioase
109
    func xAxisLabel( for itemNo: Int, of items: Int ) -> Double {
110
        let labelSpace = Double(rect!.width) / Double(items - 1)
111
        let labelRelativeValue = labelSpace * Double(itemNo - 1)
112
        return Double(rect!.origin.x) + labelRelativeValue
113
    }
114

            
115
    func placeInRect (point: CGPoint) -> CGPoint {
Bogdan Timofte authored 2 weeks ago
116
        guard let rect else {
Bogdan Timofte authored 2 weeks ago
117
            track("Invalid Context")
Bogdan Timofte authored 2 weeks ago
118
            return .zero
Bogdan Timofte authored 2 weeks ago
119
        }
120

            
Bogdan Timofte authored 2 weeks ago
121
        let width = max(rect.width, 1)
122
        let height = max(rect.height, 0.1)
123
        let x = (point.x - rect.origin.x)/width
124
        let y = (pad + point.y - rect.origin.y)/height
Bogdan Timofte authored 2 weeks ago
125
        return CGPoint(x: x, y: 1 - y * Constants.chartOverscan)
126
    }
127
}