quaternionboy
quaternionboy

Reputation: 361

Swift Charts Animation works editing values but not entering one new

I expect the line grow with animation when entering a new entry but the animation only happen when editing existing values

I don't want a canvas resize so I need to scale the canvas before the animation.

import SwiftUI
import Charts

struct Entry: Identifiable {
    var id = UUID()
    var time: Double
    var value: Double
}

struct ContentView: View {
    @State var data: [Entry] = [
        .init(time: 0, value: 0),
        .init(time: 1, value: 1)]
    var body: some View {
        VStack{
            Button("+"){
                withAnimation{
                    data.append(.init(time: 2, value: 2))
                }
            }
            Chart(data){entry in
                LineMark(x: .value("time", entry.time),
                         y: .value("value", entry.value))
            }
            .chartXScale(domain: 0...2)
            .chartYScale(domain: 0...2)
            .padding()
        }
    }
}

Upvotes: 0

Views: 250

Answers (1)

quaternionboy
quaternionboy

Reputation: 361

Duplicating last entry and editing the values while keeping the entry id generates the desired outcome:

struct LineChartAnimationPlayground4: View {
    
    struct Playground4Entry: Identifiable {
        let id = UUID()
        var date: Date
        var value: Double
    }
    
    @State private var model: [Playground4Entry]
        
    
    init(){
        model = {
            var output = [0.0,1,2,3,4,5,6,7,8,9]
                .enumerated()
                .map{i,value in
                    Playground4Entry(date: Calendar.current.date(byAdding: .day, value: i, to: .now)!,
                                     value: Double.random(in: 0...100))
                }
            output.append(output.last!)
            return output
        }()
    }
    var body: some View {
        Button("Animate"){          
            withAnimation{
                model[model.count-1].date = Calendar.current.date(byAdding: .day, value: 1, to:  model[model.count-1].date)!
                model[model.count-1].value = Double.random(in: 0...100)
                
            }
        }
        Chart{
            ForEach(model) { entry in
                LineMark(x: .value("index", entry.date),
                         y: .value("value", entry.value))
            }
        }
    }
}

#Preview("Add entry animation") {
    LineChartAnimationPlayground4()
}

Upvotes: 0

Related Questions