Files
ChartView/Sources/SwiftUICharts/Base/Chart/ChartData.swift
Andras Samu ebaaf81d19 feat: new protocol for chained functions, and added support for expli… (#252)
* feat: new protocol for chained functions, and added support for explicit Y ranges. X coming as well

* feat: add new axis interface (#253)
2022-10-24 16:07:51 +02:00

75 lines
2.2 KiB
Swift

import SwiftUI
/// An observable wrapper for an array of data for use in any chart
public class ChartData: ObservableObject {
@Published public var data: [(Double, Double)] = []
public var rangeY: ClosedRange<Double>?
public var rangeX: ClosedRange<Double>?
var points: [Double] {
data.filter { rangeX?.contains($0.0) ?? true }.map { $0.1 }
}
var values: [Double] {
data.filter { rangeX?.contains($0.0) ?? true }.map { $0.0 }
}
var normalisedPoints: [Double] {
let absolutePoints = points.map { abs($0) }
var maxPoint = absolutePoints.max()
if let rangeY = rangeY {
maxPoint = Double(rangeY.overreach)
return points.map { ($0 - rangeY.lowerBound) / (maxPoint ?? 1.0) }
}
return points.map { $0 / (maxPoint ?? 1.0) }
}
var normalisedValues: [Double] {
let absoluteValues = values.map { abs($0) }
var maxValue = absoluteValues.max()
if let rangeX = rangeX {
maxValue = Double(rangeX.overreach)
return values.map { ($0 - rangeX.lowerBound) / (maxValue ?? 1.0) }
}
return values.map { $0 / (maxValue ?? 1.0) }
}
var normalisedData: [(Double, Double)] {
Array(zip(normalisedValues, normalisedPoints))
}
var normalisedYRange: Double {
return rangeY == nil ? (normalisedPoints.max() ?? 0.0) - (normalisedPoints.min() ?? 0.0) : 1
}
var normalisedXRange: Double {
return rangeX == nil ? (normalisedValues.max() ?? 0.0) - (normalisedValues.min() ?? 0.0) : 1
}
var isInNegativeDomain: Bool {
if let rangeY = rangeY {
return rangeY.lowerBound < 0
}
return (points.min() ?? 0.0) < 0
}
/// Initialize with data array
/// - Parameter data: Array of `Double`
public init(_ data: [Double], rangeY: ClosedRange<FloatLiteralType>? = nil) {
self.data = data.enumerated().map{ (index, value) in (Double(index), value) }
self.rangeY = rangeY
}
public init(_ data: [(Double, Double)], rangeY: ClosedRange<FloatLiteralType>? = nil) {
self.data = data
self.rangeY = rangeY
}
public init() {
self.data = []
}
}