1 contributor
//
// ChartContext.swift
// USB Meter
//
// Created by Bogdan Timofte on 14/04/2020.
// Copyright © 2020 Bogdan Timofte. All rights reserved.
//
import CoreGraphics
import SwiftUI
class ChartContext {
private var rect : CGRect?
private var pad: CGFloat = 0
var isValid: Bool {
get {
return rect != nil && rect!.width > 0 && rect!.height > 0
}
}
var size: CGSize {
get {
guard rect != nil else {
track("Invalid Context")
return .zero
}
return rect!.size
}
}
var origin: CGPoint {
get {
guard rect != nil else {
track("Invalid Context")
return .zero
}
return rect!.origin
}
}
var minValue: Double {
return rect == nil ? .nan : Double(rect!.minY)
}
var maxValue: Double {
get {
return rect == nil ? .nan : Double(rect!.maxY)
}
}
func reset() {
rect = nil
pad = 0
}
func include( point: CGPoint ) {
if rect == nil {
rect = CGRect(origin: point, size: .zero)
padding()
} else {
rect = rect!.union(CGRect(origin: point, size: .zero))
padding()
}
}
func padding() {
guard rect != nil else {
track("Invalid Context")
pad = 0
return
}
pad = rect!.size.height * Constants.chartUnderscan
}
func ensureMinimumSize(width minimumWidth: CGFloat = 0, height minimumHeight: CGFloat = 0) {
guard var rect else { return }
if rect.width < minimumWidth {
let delta = (minimumWidth - rect.width) / 2
rect = rect.insetBy(dx: -delta, dy: 0)
}
if rect.height < minimumHeight {
let delta = (minimumHeight - rect.height) / 2
rect = rect.insetBy(dx: 0, dy: -delta)
}
self.rect = rect
padding()
}
func yAxisLabel( for itemNo: Int, of items: Int ) -> Double {
let labelSpace = Double(rect!.height) / Double(items - 1)
let labelRelativeValue = labelSpace * Double(itemNo - 1)
return minValue + labelRelativeValue
}
// MARK: Conversii dubioase
func xAxisLabel( for itemNo: Int, of items: Int ) -> Double {
let labelSpace = Double(rect!.width) / Double(items - 1)
let labelRelativeValue = labelSpace * Double(itemNo - 1)
return Double(rect!.origin.x) + labelRelativeValue
}
func placeInRect (point: CGPoint) -> CGPoint {
guard let rect else {
track("Invalid Context")
return .zero
}
let width = max(rect.width, 1)
let height = max(rect.height, 0.1)
let x = (point.x - rect.origin.x)/width
let y = (pad + point.y - rect.origin.y)/height
return CGPoint(x: x, y: 1 - y * Constants.chartOverscan)
}
}