Macaw
Macaw copied to clipboard
Redraw Chart
Hi. I saw someone has asked about this but the answer wasn't clear. I've subclassed Macaw and drawing the initial chart is fine. But from a view controller I can reset the data within the subclassed Macaw, but somehow I have to tell it to go ahead and recreate the chart from scratch. Update the nodes etc. But I can't find how to do that.
Someone said to go change a node and that will force a redraw, but all the nodes are created within the subclass (using the tutorial at https://www.youtube.com/watch?v=hMyExC9swz8 ).
I can't figure out how to get it to recreate everything from scratch based on data changed after init
Hi David,
Can you attach a sample? I didn't understand why you can't just adjust the properties / nodes you need.
Hi, I have a similar issue, maybe my code snippet will help. I can't seem to find a way to change the node once I have initialised it since its static. `import UIKit import Macaw
class MacawChartView: MacawView {
static var dataSet : [GraphData] = [] {
didSet {
adjustData()
}
}
static let maxValue = 100 // max value of the data in the graph
static let maxValueLineHeight = 300 // based on the view
static let lineWidth : Double = 500 // based on the view
static let dataDivisor = Double(maxValue)/Double(maxValueLineHeight)
static var adjustedData: [Double] = []
static var animations : [Animation] = []
required init?(coder aDecoder: NSCoder) {
super.init(node: MacawChartView.createChart(), coder: aDecoder)
backgroundColor = .clear
}
private static func adjustData(){
adjustedData = dataSet.map({ $0.Score / dataDivisor })
}
private func reinit(){
super.node = MacawChartView.createChart()
}
private static func createChart() -> Group {
var items = addYaxisItems() + addXaxisItems()
items.append(createBars())
return Group(contents: items, place: .identity)
}
private static func addYaxisItems() -> [Node] {
let maxlines = 10
let lineInterval = Int(maxValue/maxlines)
let YaxisHeight : Double = 300
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.black.with(a: 0.10))
let valueText = Text(text: "\(i * lineInterval)", align: .max, baseline: .mid, place: .move(dx: -10, dy: y))
valueText.fill = Color.black
newNodes.append(valueLine)
newNodes.append(valueText)
}
let yAxis = Line(x1: 0, y1: 0, x2: 0, y2: YaxisHeight).stroke(fill: Color.black.with(a: 0.25))
newNodes.append(yAxis)
return newNodes
}
private static func addXaxisItems() -> [Node] {
let chartBaseY : Double = 300
var newNodes : [Node] = []
if(adjustedData.count > 0){
for i in 1...adjustedData.count {
let x = (Double(i) * 50 )
let valueText = Text(text: dataSet[i - 1].Concept, align: .max, baseline: .mid,place: .move(dx: x, dy: chartBaseY + 15))
valueText.fill = Color.black
newNodes.append(valueText)
}
}
let xAxis = Line(x1: 0, y1: chartBaseY, x2: lineWidth, y2: chartBaseY).stroke(fill: Color.black.with(a: 0.25))
newNodes.append(xAxis)
return newNodes
}
private static func createBars() -> Group {
let fill = LinearGradient(degree: 90, from: Color.init(val: 0xff4704), to: Color(val: 0xff4704).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
let rect = Rect(x: Double(i) * 50 + 25, y: 300 - height , w: 30, h: height)
return [rect.fill(with: fill)]
}
}
return items.group()
}
static func playAnimations(){
animations.combine().play()
}
private static func data() -> [GraphData] {
return []
}
}`
Even I wanted to reinitialize the UI corresponding to the App theme being switched. I don't know which method or approach to redraw the Macaw View.
I tried to invoke createMacawView in my ViewController's "ViewDidAppear" method but no avail.
The problem also is that Macaw doesn't support theme changes by default - you can help us and send us a PR with this functionality. Actually I have some experience with Texture (Texture has own rendering system based on UIKit as Macaw) and theme changes in iOS 13, actually, I can check the possibility to refactor some Macaw classes.
I followed the same tutorial @PunkStarStudios and @zyrondias, did either of you figure out how to update the bar chart with new data once it was already created? Thank you!
https://stackoverflow.com/questions/63216461/value-changed-but-the-chart-doesnt-swift