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.
@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})