// // HistoryGraphViewController.swift // pocloud // // Created by Patrick McDonagh on 5/29/18. // Copyright © 2018 patrickjmcd. All rights reserved. // import UIKit import SwiftChart class HistoryGraphViewController: UIViewController, ChartDelegate{ let user = (UIApplication.shared.delegate as! AppDelegate).user let channelDataTypes = (UIApplication.shared.delegate as! AppDelegate).channelDataTypes @IBOutlet weak var leftConstraint: NSLayoutConstraint! @IBOutlet weak var lineChart: Chart! @IBOutlet weak var label: UILabel! var thisChannel : Channel? var channelHistory : [ChannelHistoryValue] = [ChannelHistoryValue]() var dateFormatter = DateFormatter() override func viewDidLoad() { super.viewDidLoad() dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" lineChart.delegate = self loadChartData() } func loadChartData() { switch channelDataTypes[(thisChannel?.dataType)!] { case "Float", "Integer": let seriesData : [(x: Int, y: Double)] = channelHistory.map { (chHist) -> (x: Int, y: Double) in (x: Int(chHist.timestamp!.timeIntervalSince1970), y:Double(chHist.value)!) } lineChart.add(ChartSeries(data: seriesData)) setupLineChart() default: let alert = UIAlertController(title: "Invalid Type", message: "This channel is of type \(channelDataTypes[(thisChannel?.dataType)!] ?? "ERROR") and cannot be graphed yet.", preferredStyle: .alert) let ok = UIAlertAction(title: "OK", style: .cancel, handler: { _ in self.navigationController?.popViewController(animated: true) }) alert.addAction(ok) present(alert, animated: true) } } func setupLineChart() { let xLabelMax = lineChart.series.first?.data.first?.x let xLabelMin = lineChart.series.first?.data.last?.x let xLabelDoubles = [0.0, 0.25, 0.5, 0.75, 1.0].map { (multiplier) -> Double in xLabelMin! + (xLabelMax! - xLabelMin!) * multiplier } lineChart.xLabels = xLabelDoubles self.dateFormatter.dateFormat = "HH:mm:ss" lineChart.xLabelsFormatter = { (i, d) -> String in self.dateFormatter.string(from: Date(timeIntervalSince1970: d)) } lineChart.bottomInset = 40 lineChart.series.first?.area = true } func didTouchChart(_ chart: Chart, indexes: Array, x: Double, left: CGFloat) { for (seriesIndex, dataIndex) in indexes.enumerated() { if dataIndex != nil { let value = chart.valueForSeries(seriesIndex, atIndex: dataIndex) let valueFormat = self.channelDataTypes[(self.thisChannel?.dataType)!]! == "Integer" ? "%d" : "%.3f" let valueString = String(format: valueFormat, value!) self.dateFormatter.dateFormat = "yyyy-MM-dd HH:mm:ss" let timestamp = self.dateFormatter.string(from: channelHistory[dataIndex!].timestamp!) self.label.text = "\(valueString) @ \(timestamp)" let intendedLeftPosition = left - (0.5 * self.label.frame.width) if intendedLeftPosition < 8 { self.leftConstraint.constant = 8 } else if (intendedLeftPosition + self.label.frame.width) > (self.view.frame.width - 8) { self.leftConstraint.constant = self.view.frame.width - (8 + self.label.frame.width) } else { self.leftConstraint.constant = intendedLeftPosition } } } } func didFinishTouchingChart(_ chart: Chart) { label.text = "" } func didEndTouchingChart(_ chart: Chart) { } }