0

I have a macOS App written in Swift and I need to visualise some temperatures sensors like a Charts. The project doesn't use SwiftUI, but only for this view.

I've created this View and works fine. Now I need to enable users zoom over the chart (zooming only x-axis) by pinch with fingers on trackpad and by using +/- buttons in page. And second, I need to show a popup with single point information when the user pass mouse over the charts.

I've tried many way, but I'm really new in SwiftUI (and to be honest I don't like it) and I can't find the right way to achieve this two functionalities.

This is the code I have written until now (with a lot of effort). Can you help me ? Thanks.

struct LineChartSerie: Identifiable {
   let id = UUID()
   let label: String
   let points: [LineChartPoint]
   let color: Color
}

struct LineChartPoint: Identifiable {
   let id = UUID()
   let x: Int
   let y: Double
}

struct LineChart: View {
   
   private var series: [LineChartSerie] = []
   
   init(_ series: [LineChartSerie]) {
      changeSeries(series)
   }
   
   mutating func changeSeries(_ series: [LineChartSerie]) {
      self.series = series
   }
   
   var body: some View {
      Chart {
         ForEach(series) { serie in
            ForEach(serie.points) { point in
               LineMark(x: .value("Time", point.x),
                        y: .value("Temp", point.y)
               )
               .foregroundStyle(serie.color)
               .position(by: .value("Label", serie.label))
               .foregroundStyle(by: .value("Label", serie.label))
               .interpolationMethod(Charts.InterpolationMethod.linear)
               .symbol {
                  Circle()
                     .fill(serie.color)
                     .frame(width: 0)
               }
            }
         }
      }
      .chartYAxis {
         AxisMarks(position: .leading, values: .automatic(desiredCount: 30)) { value in
            AxisGridLine()
            AxisValueLabel {
               if let intValue = value.as(Int.self) {
                  Text("\(intValue) C°")
               }
            }
         }
      }
      .chartYAxisLabel("Temperature")
      .chartXAxis {
         AxisMarks(values: .automatic(desiredCount: 25)) { value in
            AxisGridLine()
            AxisTick()
            AxisValueLabel {
               if let intValue = value.as(Int.self) {
                  Text(getTimeFromSeconds(intValue))
               }
            }
         }
      }
      .chartXScale(domain: [0,86_400])
      .chartXAxisLabel("Time in the day")
      .chartForegroundStyleScale(range: graphColors(for: series))
      .chartLegend (position: .bottom, alignment: .leading)
      .clipped()
      
   }
}
Fry
  • 6,235
  • 8
  • 54
  • 93

0 Answers0