SwiftUI IOS CorePlot Send API Data to Graph

117 Views Asked by At

I'm not sure how to integrate my API fetch code to be used in my graph. Is it possible to modify my existing codes to have the API values sent to the X and Y axis of my graph accordingly? If so, How should I do that in terms of code placement and etc? I am looking to use the forEach function to decode each value, Voltage, Current, Temperature, and time. With Voltage, Current and Temperature to X-axis while times to Y-axis.

Current CorePlot Code:

import Foundation
import SwiftUI
import CorePlot

class CalculatePlotData: ObservableObject {
    
    var plotDataModel: PlotDataClass? = nil
    

    func plotYEqualsX()
    {
        
        //set the Plot Parameters
        plotDataModel!.changingPlotParameters.yMax = 10.0
        plotDataModel!.changingPlotParameters.yMin = -5.0
        plotDataModel!.changingPlotParameters.xMax = 10.0
        plotDataModel!.changingPlotParameters.xMin = -5.0
        plotDataModel!.changingPlotParameters.xLabel = "x"
        plotDataModel!.changingPlotParameters.yLabel = "y"
        plotDataModel!.changingPlotParameters.lineColor = .red()
        plotDataModel!.changingPlotParameters.title = " y = x"
        
        plotDataModel!.zeroData()
        var plotData :[plotDataType] =  []
        
        
        for i in 0 ..< 120 {

            //create x values here

            let x = -2.0 + Double(i) * 0.2

        //create y values here

        let y = x * 8


            let dataPoint: plotDataType = [.X: x, .Y: y]
            plotData.append(contentsOf: [dataPoint])
        
        }
        
        plotDataModel!.appendData(dataPoint: plotData)
        
        
    }
    
    
    func ploteToTheMinusX()
    {
        
        //set the Plot Parameters
        plotDataModel!.changingPlotParameters.yMax = 10
        plotDataModel!.changingPlotParameters.yMin = -3.0
        plotDataModel!.changingPlotParameters.xMax = 10.0
        plotDataModel!.changingPlotParameters.xMin = -3.0
        plotDataModel!.changingPlotParameters.xLabel = "x"
        plotDataModel!.changingPlotParameters.yLabel = "y = exp(-x)"
        plotDataModel!.changingPlotParameters.lineColor = .blue()
        plotDataModel!.changingPlotParameters.title = "exp(-x)"

        plotDataModel!.zeroData()
        var plotData :[plotDataType] =  []
        for i in 0 ..< 60 {

            //create x values here

            let x = -8.0 + Double(i) * 5

        //create y values here

        let y = exp(-x)
            
            let dataPoint: plotDataType = [.X: x, .Y: y]
            plotData.append(contentsOf: [dataPoint])
        }
        
        plotDataModel!.appendData(dataPoint: plotData)
        
        return
    }
    
}

Sample Code to fetch API data to IOS App:

import Foundation

struct datamainjsonlatest: Codable, Identifiable {
    var id: String
    var times: String
    var Voltage: String
    var Current: String
    var Temperature: String
}


class Api : ObservableObject{
    @Published var datamainjsonlatests = [datamainjsonlatest]()
    
    func loadData(completion:@escaping ([datamainjsonlatest]) -> ()) {
        guard let url = URL(string: "https://dcmicrogridiep.000webhostapp.com/datamainlatestjson.php") else {
            print("Invalid url...")
            return
        }

        URLSession.shared.dataTask(with: url) { data, response, error in
            let datamainjsonlatests = try! JSONDecoder().decode([datamainjsonlatest].self, from: data!)
            print(datamainjsonlatests)
            DispatchQueue.main.async {
                completion(datamainjsonlatests)
            }
        }.resume()
        
    }
}
1

There are 1 best solutions below

0
Eric Skroch On
  1. Call reloadData on the graph whenever you retrieve new data to force the graph to update. Remember to call it from the main queue.

  2. In the plot datasource, the numberOfRecords(for:) method should return datamainjsonlatests.count. If you're filtering the data range for better drawing performance, adjust this count accordingly.

  3. This is datasource method is from one of the Core Plot example apps:

    func number(for plot: CPTPlot, field: UInt, record: UInt) -> Any?
    {
        switch CPTScatterPlotField(rawValue: Int(field))! {
        case .X:
            return (oneDay * Double(record)) as NSNumber
            
        case .Y:
            return self.plotData[Int(record)] as NSNumber

        @unknown default:
            return nil
        }
    }

Change the .X and .Y cases to whatever conversions are needed for your data in datamainjsonlatests. If it's easier to provide data in an array, see the CPTPlotDataSource Protocol Reference for the other available datasource methods. You datasource must include the numberOfRecords(for:) method and one of the others.