值已更改但图表未更改 Swift
Value changed but the chart doesn't Swift
我正在为我的图表使用 Macaw 框架。只有一个问题,如果它第一次显示“X”图表,它将始终(直到关闭应用程序)显示“X”图表。但是数据在变化(我在调试器里看到了)。
这是我的“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()
}
这是我的 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({[=12=].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()
}
}
我将我的 createData() 函数声明为全局函数(不在 VC 中)。问题是数据在变化,但图表没有。它始终显示相同的图表。
尝试在 updateDisplay()
函数结束时调用 setNeedsLayout()
。
@Russel 给我很好的建议。问题是我没有更新真正更新图表的 adjustedData
。我在 updateDisplay
中添加了这段代码,它成功了。
MacawChartView.adjustedData = MacawChartView.chartData.map({[=10=].percentage / MacawChartView.dataDivisor})
我正在为我的图表使用 Macaw 框架。只有一个问题,如果它第一次显示“X”图表,它将始终(直到关闭应用程序)显示“X”图表。但是数据在变化(我在调试器里看到了)。
这是我的“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()
}
这是我的 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({[=12=].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()
}
}
我将我的 createData() 函数声明为全局函数(不在 VC 中)。问题是数据在变化,但图表没有。它始终显示相同的图表。
尝试在 updateDisplay()
函数结束时调用 setNeedsLayout()
。
@Russel 给我很好的建议。问题是我没有更新真正更新图表的 adjustedData
。我在 updateDisplay
中添加了这段代码,它成功了。
MacawChartView.adjustedData = MacawChartView.chartData.map({[=10=].percentage / MacawChartView.dataDivisor})