Hin und wieder muss ich Daten in ansprechenden Diagrammen visualisieren. Dieser Beitrag zeigt, wie man Diagramme in einer SwiftUI-Anwendung zeichnet.
Ein Diagramm-Paket von Grund auf neu zu starten war aufgrund von Zeit- und Budgetbeschraenkungen keine Option, also habe ich nach bestehenden Loesungen gesucht.
Meine Wahl fiel auf SwiftUI-Charts, das ansprechende Grafiken und einfache Integration bietet.
Setup und Projektkonfiguration
Wir beginnen mit der Erstellung eines Projekts in Xcode.

Der Ausgangspunkt ist die Standard-SwiftUI-Anwendung, die modifiziert wird.

Als Naechstes fuege das Paket hinzu, indem du die Projekteinstellungen oeffnest.

Druecke den “Plus”-Button, um ein neues Paket hinzuzufuegen. Gib die Repository-URL ein: https://github.com/spacenation/swiftui-charts.git.

Auf dem naechsten Bildschirm habe ich die Standardeinstellungen belassen.

Auf dem letzten Bildschirm habe ich ebenfalls die Standardwerte akzeptiert.

Konstante Daten anzeigen
Zeit, Code hinzuzufuegen. Fuer einen ersten Test habe ich ein Snippet aus der GitHub-README verwendet und es in ContentView eingefuegt:
import Charts
import SwiftUI
struct ContentView: View {
var body: some View {
Chart(data: [0.1, 0.3, 0.2, 0.5, 0.4, 0.9, 0.1])
.chartStyle(
LineChartStyle(.quadCurve, lineColor:.blue, lineWidth: 5)
)
}
}Das Ausfuehren im Simulator zeichnet einen Graphen der konstanten Werte.

Dies qualifiziert sich als erfolgreicher erster Test.
Dynamische Daten anzeigen
In meiner Arbeit aendern sich die Daten, die ich visualisiere, im Laufe der Zeit (zum Beispiel Sensoreingaben). Lass uns das Beispiel erweitern, um den Graphen dynamisch zu aktualisieren.
Der “Sensor” wird eine Klasse sein, die ObservableObject implementiert und alle 500 Millisekunden einen zufaelligen Double-Wert veroeffentlicht.
import Foundation
class ValuePublisher: ObservableObject {
@Published var value: Double = 0.0
init() {
Timer.scheduledTimer(withTimeInterval: 0.5, repeats: true) { timer in
self.value = Double.random(in: 0...1.0)
}
}
}Instanziiere dies in ContentView als @StateObject:
@StateObject var valuePublisher = ValuePublisher()ValuePublisher sendet einzelne Werte, aber wir brauchen eine Liste von Werten. Eine einfache Queue-Struktur loest das Problem.
struct Queue<T> {
var list = [T]()
mutating func enqueue(_ element: T) {
list.append(element)
}
mutating func dequeue() -> T? {
if!list.isEmpty {
return list.removeFirst()
} else {
return nil
}
}
func peek() -> T? {
if!list.isEmpty {
return list[0]
} else {
return nil
}
}
}Instanziiere die Queue als @State-Variable in ContentView:
@State var doubleQueue = Queue<Double>()Initialisiere die zugrunde liegende Liste, wenn die View erscheint:
.onAppear {
doubleQueue.list = [Double](repeating: 0.0, count: 50)
}Sage dem Diagramm, die Liste von Werten zu verwenden:
Chart(data: doubleQueue.list)Fuege schliesslich veroeffentlichte Werte von ValuePublisher zur Queue hinzu und entferne den aeltesten Wert:
.onChange(of: valuePublisher.value) { value in
self.doubleQueue.enqueue(value)
_ = self.doubleQueue.dequeue()
}Das war’s im Wesentlichen. Hier ist die vollstaendige ContentView, in der ich auch das Erscheinungsbild des Graphen angepasst habe:
import Charts
import SwiftUI
struct ContentView: View {
@State var doubleQueue = Queue<Double>()
@StateObject var valuePublisher = ValuePublisher()
var body: some View {
Chart(data: doubleQueue.list)
.chartStyle(
AreaChartStyle(.quadCurve, fill:
LinearGradient(gradient:.init(colors: [Color.blue.opacity(1.0), Color.blue.opacity(0.5)]), startPoint:.top, endPoint:.bottom)
)
)
.onAppear {
doubleQueue.list = [Double](repeating: 0.0, count: 50)
}
.onChange(of: valuePublisher.value) { value in
self.doubleQueue.enqueue(value)
_ = self.doubleQueue.dequeue()
}
.padding()
}
}Screenshot der fertigen Anwendung:

Ich habe auch ein Video hochgeladen, das die dynamisch aktualisierten Werte zeigt:
Gerne kannst du mir einen Kaffee ausgeben, wenn dir dieser Beitrag gefallen hat.