Search code examples
iosswiftxcodemacaw

Value changed but the chart doesn't Swift


I'm using the Macaw framework for my charts. There's only one problem that if it the first time shows the "X" chart, it will always(until closing app) show the "X" chart. But the data is changing(I saw it in the debugger).

Here is the snippet of my "DahlichViewController".

class DahlichViewController: UIViewController {
    
@IBOutlet private var chartView: MacawChartView!
@IBOutlet weak var start: UIButton!
    
override func viewDidLoad() {
    super.viewDidLoad()
    chartView.backgroundColor = .clear
    chartView.contentMode = .scaleAspectFit
}

@IBAction func startPressed(_ sender: UIButton) {
    chartView.updateData(newData: createData())
    chartView.playAnimations()
}

And here's my MacawChartView.

import Foundation
import Macaw

class MacawChartView: MacawView {
    
    static var chartData = createData()
    
    static let maxValue              = 60
    static let maxValueLineHeight    = 18
    static let lineWidth: Double     = 275
    
    static let dataDivisor             = Double(maxValue/maxValueLineHeight)
    static let adjustedData: [Double]  = chartData.map({$0.percentage / dataDivisor})
    static var animations: [Animation] = []
    
    public func updateData(newData : [ElectionBrain])
    {
        MacawChartView.chartData = newData
        updateDisplay()
    }

    public func updateDisplay()
    {
        let chart = MacawChartView.createChart()
        self.node = Group(contents: [chart])
    }
    
    static func createChart() -> Group {
        var items: [Node] = addYAxisItems() + addXAxisItems()
        items.append(createBars())
        
        return Group(contents: items, place: .identity)
    }
    
    private static func addYAxisItems() -> [Node] {
        let maxLines            = 6
        let lineInterval        = Int(maxValue / maxLines)
        let yAxisHeight: Double = 200
        let lineSpacing: Double = 30
        
        var newNodes: [Node]    = []
        
        for i in 1...maxLines {
            let y = yAxisHeight - (Double(i) * lineSpacing)
            
            let valueLine = Line(x1: -5, y1: y, x2: lineWidth, y2: y).stroke(fill: Color.white.with(a: 0.10))
            let valueText = Text(text: "\(i * lineInterval)", align: .max, baseline: .mid, place: .move(dx: -10, dy: y))
            valueText.fill = Color.white
            
            newNodes.append(valueLine)
            newNodes.append(valueText)
        }
        
        let yAxis = Line(x1: 0, y1: 0, x2: 0, y2: yAxisHeight).stroke(fill: Color.white.with(a: 0.25))
        newNodes.append(yAxis)
        
        return newNodes
    }
    
    private static func addXAxisItems() -> [Node] {
        let chartBaseY: Double = 200
        var newNodes: [Node]   = []
        
        
        for i in 1...adjustedData.count {
            let x = (Double(i) * 50)
            let valueText = Text(text: chartData[i - 1].version, align: .max, baseline: .mid, place: .move(dx: x, dy: chartBaseY + 15))
            valueText.fill = Color.white
            newNodes.append(valueText)
        }
        
        let xAxis = Line(x1: 0, y1: chartBaseY, x2: lineWidth, y2: chartBaseY).stroke(fill: Color.white.with(a: 0.25))
        newNodes.append(xAxis)
        
        return newNodes
    }
    
    private static func createBars() -> Group {
        let fill  = LinearGradient(degree: 90, from: Color(val: 0xfff264), to: Color(val: 0xd69c00).with(a: 0.33))
        let items = adjustedData.map { _ in Group() }
        
        animations = items.enumerated().map { (i: Int, item: Group) in
            item.contentsVar.animation(delay: Double(i) * 0.1 ) { t in
                let height = adjustedData[i] * t * 10
                let rect   = Rect(x: Double(i) * 50 + 25, y: 200 - height, w: 30, h: height)
                return[rect.fill(with: fill)]
            }
        }
        
        return items.group()
    }
    
     func playAnimations() {
        MacawChartView.animations.combine().play()
    }

}

I declared my createData() function as global function(Not in VC). The problem is that data is changing but the chart doesn't. It all time shows the same chart.


Solution

  • @Russel give me good advice. The problem was that I didn't update the adjustedData which truly updates the chart. I added this code in updateDisplay and it has worked.

            MacawChartView.adjustedData = MacawChartView.chartData.map({$0.percentage / MacawChartView.dataDivisor})