ios – SwiftUI ➙ Swift Chart: How can I use a variable to choose which vector(?) in my struct to plot?


I am trying to reuse a SwiftUI Swift Chart view instead of having six separately defined Chart views. (The six separate charts ARE working fine)

Q: How does one use a var to represent different “columns” of data from my array of structs I want to be plotted.

(element.xGyroelement.yGyro ) in the y: .value("xGyro", element.xGyro)

To reduce code duplication, I’d rather not use a switch/case statement for the whole Chart {} block.

I did try using a switch/case for just the y: .value... line but I got an error.

What I don’t know how to do is replace the (currently) hard-coded element.xGyro with a variable that I can pass in to plot different points [ xGyro | yGyro | zGyro | xAccel | yAccel | zAccel ] in the following line with a variable.

y: .value("xGyro", element.xGyro)

The source for my charts is an array of structs MotionDataPointClass.swift:

class MotionDataPointM: Identifiable {
   var xGyro: Double
   var yGyro: Double
   var zGyro: Double
   var xAccel: Double
   var yAccel: Double
   var zAccel: Double
   var timeStamp: Date
   var myIndex: Int
   var id: Date { timeStamp }
}

The chart code is SingleChartView.swift

import os
import SwiftUI
import CoreMotion
import CoreLocation
import Charts


struct SingleChartView: View {
   @ObservedObject var locationsHandler = LocationsHandler.shared
   let motionDataPoints: [MotionDataPointM]
   
   let numberOfPointsToPlot: Int
   let vertScaleMin: Double
   let vertScaleMax: Double
   let cornerLabel: String
   let lineColor: Color
   let valuesToPlot: Int
   
   var body: some View {
      Chart{
         ForEach(motionDataPoints.suffix(numberOfPointsToPlot)) { element in
            LineMark(
               x: .value("Date", element.timeStamp),

y: .value("xGyro", element.xGyro)

            )
         }
         .interpolationMethod(.catmullRom)
      }
      .foregroundStyle(lineColor)
      .chartYScale(domain: [vertScaleMin, vertScaleMax])
      .padding(.top, 10.0)
      .padding(.bottom, 3.0)
      .padding(.horizontal, 3.0)
      .overlay(
         RoundedRectangle(cornerRadius: 10)
            .stroke(Color.purple, lineWidth: 1.0)
      )
      .overlay(
         HStack {
            VStack {
               Text("\(cornerLabel)")
                  .font(.largeTitle)
                  .fontWeight(.black)
                  .foregroundColor(lineColor)
                  .opacity(0.3)
                  .padding(.leading, 4)
                  .padding(.top, -3)
               Spacer()
            }
            Spacer()
         }
      )
   }
}

I am calling/invoking the chart from my ContentView.swift file…

SingleChartView(motionDataPoints: motionDataPoints, numberOfPointsToPlot: numberOfPointsToPlot, vertScaleMin: gyroMinX, vertScaleMax: gyroMaxX, cornerLabel: "W", lineColor: Color("YChartLines"), valuesToPlot: vectorToPlot.xGyro)

I defined an enum to represent the different columns/vectors in the data struct…

enum vectorToPlot {
   public static let xGyro = 1
   public static let yGyro = 2
   public static let zGyro = 3
   public static let xAccel = 4
   public static let yAccel = 5
   public static let zAccel = 6
}

Latest articles

spot_imgspot_img

Related articles

Leave a reply

Please enter your comment!
Please enter your name here

spot_imgspot_img