I want to handle the time vary between different values in chart so easily like it’s in e.g. the iOS Well being app. modify the vary of the chart between e.g. a 3-mouth view and a 9-mouth view?
That is my code:
import SwiftUI
import Charts
struct ChartsV: View {
@State personal var isSheetPresented = false
@State var contentHasScrolled = false
@ObservedObject var dataStore: DataStoreVM
@State personal var kind: Int = 0
init(dataStore: DataStoreVM) {
self.dataStore = dataStore
let navBarAppearance = UINavigationBarAppearance()
UINavigationBar.look().standardAppearance = navBarAppearance
}
var physique: some View {
NavigationView {
ZStack {
LinearGradient(
gradient: Gradient(stops: [
.init(color: Color(uiColor: .systemBackground), location: 0.1),
.init(color: colorForType(chartType: type), location: 0.7),
.init(color: Color(uiColor: .systemBackground), location: 1.2)
]),
startPoint: .prime,
endPoint: .backside
)
.animation(.easeInOut(period: 0.6), worth: kind)
.masks(
LinearGradient(
gradient: Gradient(stops: [
.init(color: Color.black.opacity(0.3), location: -0.5),
.init(color: Color.black.opacity(0.5), location: 0.5),
.init(color: Color.black.opacity(0.3), location: 1.5)
]),
startPoint: .main,
endPoint: .trailing
)
)
.edgesIgnoringSafeArea(.all)
VStack {
Textual content("Wykresy")
.foregroundColor(.main)
.opacity(0.5)
.fontWeight(.daring)
.padding()
Chart(dataStore.entries) { entry in
LineMark(
x: .worth("Month", entry.date),
y: .worth("Whole", valueForType(entry: entry, chartType: kind))
)
.foregroundStyle(colorForType(chartType: kind))
.lineStyle(StrokeStyle(lineWidth: 8, lineCap: .spherical))
.interpolationMethod(.monotone)
}
.chartScrollableAxes(.horizontal)
.chartYScale(area: getYMin()...getYMax())
.body(peak: 200)
.chartXAxis {
AxisMarks(place: .backside, values: .stride(by: .month)) { worth in
AxisValueLabel(format: .dateTime.month(.abbreviated))
AxisTick()
AxisGridLine()
}
}
.chartYAxis {
}
.animation(.timingCurve(0.2, 0.5, 0, 1, period: 0.8), worth: kind)
Picker("Typ", choice: $kind) {
Picture(systemName: "dollarsign").tag(0)
Picture(systemName: "fuelpump.fill").tag(1)
Picture(systemName: "street.lanes").tag(2)
Picture(systemName: "bubbles.and.sparkles.fill").tag(3)
}
.pickerStyle(.segmented)
.padding()
}
.background(.thinMaterial)
.cornerRadius(20)
.shadow(colour: .black.opacity(0.1), radius: 10, x: 0, y: 10)
.padding([.leading, .bottom, .trailing])
NavigationBarV(backgroundColor: Shade(UIColor.bgGradient1), title: "Wykresy", again: "Podsumowanie", contentHasScrolled: $contentHasScrolled)
VStack {
Spacer()
HStack {
Spacer()
BottomButtonV(bottomButton: BottomButtonM(icon: "plus", colour: Shade.main)) {
isSheetPresented.toggle()
}
}
.padding()
}
VStack {
Spacer()
Picker("Typ", choice: $kind) {
Textual content("weeks").tag(0)
Textual content("months").tag(1)
}
.pickerStyle(.segmented)
.padding(.horizontal, 80)
}
}
.sheet(isPresented: $isSheetPresented) {
NewEntryV(dataStore: dataStore) {
isSheetPresented = false
}
}
}
}
personal func getYMax() -> Double {
let maxValue = dataStore.entries.map { valueForType(entry: $0, chartType: kind) }.max() ?? 1
return max(maxValue, 1) * 1.1 // Możesz również dodać wartość do stałego minimal
}
personal func getYMin() -> Double {
let values = dataStore.entries.map { valueForType(entry: $0, chartType: kind) }
let maxValue = values.max() ?? 1
// Jeśli wszystkie wartości są zerowe
if values.allSatisfy({ $0 == 0 }) {
return -0.1 // Ustal dolną granicę na -0.1
} else {
// Ustal dolną granicę na 5% górnej wartości
return max(0, maxValue * 0.95) * -0.1
}
}
personal func valueForType(entry: Entry, chartType: Int) -> Double {
change chartType {
case 0: return entry.worth ?? 0
case 1: return entry.amount ?? 0
case 2: return entry.journey ?? 0
case 3: return entry.amount ?? 0
default: return 0
}
}
personal func colorForType(chartType: Int) -> Shade {
change chartType {
case 0: return .orange
case 1: return .inexperienced
case 2: return .blue
case 3: return .purple
default: return .main
}
}
}
I would love the chart to show totally different information relying on the chosen phase (first picker): bills, gasoline consumption, distance traveled and variety of washes. Every level on every chart needs to be the sum of values of a given kind from every week, within the case of a weekly view, and every month, within the case of a month-to-month view. Nonetheless, this isn’t crucial factor. Primarily, I want to obtain clean switching between x-axis ranges. This could easily slender and widen relying on the chosen view, in order that it shows a spread of about 3 months on the width of the view, and the division is made relative to the primary day of the week (e.g. 4 Nov, 11 Nov, 18 Nov, 25 Nov, 2 Dec) or about 9 months, and the division shows solely the names of the months.