Channel statistics improvements

This commit is contained in:
Ilya Laktyushin
2020-03-12 05:01:21 +04:00
parent d8b99880ea
commit f5dbf47b68
154 changed files with 6186 additions and 10908 deletions

View File

@@ -0,0 +1,103 @@
//
// ChardData.swift
// GraphTest
//
// Created by Andrei Salavei on 3/11/19.
// Copyright © 2019 Andrei Salavei. All rights reserved.
//
import Foundation
#if os(macOS)
import Cocoa
#else
import UIKit
#endif
import Foundation
#if os(macOS)
import Cocoa
#else
import UIKit
#endif
public struct ChartsCollection {
public struct Chart {
public internal(set) var color: GColor
public internal(set) var name: String
public internal(set) var values: [Double]
}
public internal(set) var axisValues: [Date]
public internal(set) var chartValues: [Chart]
static let blank = ChartsCollection(axisValues: [], chartValues: [])
var isBlank: Bool {
return axisValues.isEmpty || chartValues.isEmpty
}
}
public extension ChartsCollection {
public init(from decodedData: [String: Any]) throws {
guard let columns = decodedData["columns"] as? [[Any]] else {
throw ChartsError.generalConversion("Unable to get columns from: \(decodedData)")
}
guard let types = decodedData["types"] as? [String: String] else {
throw ChartsError.generalConversion("Unable to get types from: \(decodedData)")
}
guard let names = decodedData["names"] as? [String: String] else {
throw ChartsError.generalConversion("Unable to get names from: \(decodedData)")
}
guard let colors = decodedData["colors"] as? [String: String] else {
throw ChartsError.generalConversion("Unable to get colors from: \(decodedData)")
}
// chart.colors Color for each variable in 6-hex-digit format (e.g. "#AAAAAA").
// chart.names Name for each variable.
// chart.percentage true for percentage based values.
// chart.stacked true for values stacking on top of each other.
// chart.y_scaled true for charts with 2 Y axes.
var axixValuesToSetup: [Date] = []
var chartToSetup: [Chart] = []
for column in columns {
guard let columnId = column.first as? String else {
throw ChartsError.generalConversion("Unable to get column name from: \(column)")
}
guard let typeString = types[columnId], let type = ColumnType(rawValue: typeString) else {
throw ChartsError.generalConversion("Unable to get column type from: \(types) - \(columnId)")
}
switch type {
case .axix:
axixValuesToSetup = try column.dropFirst().map { Date(timeIntervalSince1970: try Convert.doubleFrom($0) / 1000) }
case .chart, .bar, .area, .step:
guard let colorString = colors[columnId],
let color = GColor(hexString: colorString) else {
throw ChartsError.generalConversion("Unable to get color name from: \(colors) - \(columnId)")
}
guard let name = names[columnId] else {
throw ChartsError.generalConversion("Unable to get column name from: \(names) - \(columnId)")
}
let values = try column.dropFirst().map { try Convert.doubleFrom($0) }
chartToSetup.append(Chart(color: color,
name: name,
values: values))
}
}
guard axixValuesToSetup.isEmpty == false,
chartToSetup.isEmpty == false,
chartToSetup.firstIndex(where: { $0.values.count != axixValuesToSetup.count }) == nil else {
throw ChartsError.generalConversion("Saniazing: Invalid number of items: \(axixValuesToSetup), \(chartToSetup)")
}
self.axisValues = axixValuesToSetup
self.chartValues = chartToSetup
}
}
private enum ColumnType: String {
case axix = "x"
case chart = "line"
case area = "area"
case bar = "bar"
case step = "step"
}