ios – handle “vary” of the x-axis in SwiftUI Charts?

0
22
ios –  handle “vary” of the x-axis in SwiftUI Charts?


My chart
Apple chart

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.

LEAVE A REPLY

Please enter your comment!
Please enter your name here