图表的折线图无法正确呈现折线图

Charts' line chart doesn't render line chart properly

我正在使用图表框架,但在我的折线图中遇到了一些非常奇怪的行为。

当我转到 ChartViewContoller 并且默认 selection 有数据时,图表正常呈现:

但是如果我在默认 selection 没有任何数据并且 then select 有数据的项目时转到这个视图控制器,看起来像这样:

1) 转至此:

2) 然后 select 一个包含数据的项目:

当然 viewDidLoad 在我转到视图控制器时会被调用,只要默认的 selection 在我转到它时有数据,我就可以 select 另一个项目有数据或没有数据,图表将继续正确呈现。所以差异似乎在 viewDidLoad 中,但我已经尝试了我能想到的一切,但没有解决问题。这是我的 viewDidLoad:

 override func viewDidLoad() {
    super.viewDidLoad()

    view.backgroundColor = UIColor(hexString: "232B35")

    self.title = "1RM"

    chartView.delegate = self
    chartView.chartDescription?.enabled = false

    let leftAxis = chartView.leftAxis
    leftAxis.axisMinimum = 190
    leftAxis.labelTextColor = NSUIColor.white

    let xAxis = chartView.xAxis
    xAxis.labelPosition = .bottom
    xAxis.axisMinimum = 0
    xAxis.granularity = 1
    xAxis.axisLineWidth = 5
    xAxis.valueFormatter = self
    xAxis.labelTextColor = NSUIColor.white


    chartView.configureDefaults()
    chartView.rightAxis.enabled = false // this fixed the extra xAxis grid lines

    chartView.backgroundColor = NSUIColor(red: 35/255.0, green: 43/255.0, blue: 53/255.0, alpha: 1.0)

    fetchData()

    chartView.setVisibleXRangeMaximum(7)

    chartView.animate(yAxisDuration: 1.0)
}

这是 fetchData() 中发生的事情:

func fetchData() {

    chartView.data = nil

    let liftName = UserDefaults.selectedLiftForChart()
    let liftEvents = dataManager.fetchLiftsEventsOfTypeByName(liftName)

    guard liftEvents.count > 0 else {
        chartView.noDataText = "There's no \(liftName) data to display"
        shouldHideData = true

        return }

    // put them into a Dictionary grouped by each unique day
    let groupedEvents = Dictionary(grouping: liftEvents, by: { floor([=11=].date.timeIntervalSince1970 / 86400) })

    // grab the maximum 1RM from each day
    let dailyMaximums = groupedEvents.map { .max(by: { [=11=].oneRepMax < .oneRepMax }) }

    // MARK: - TODO: Fix the silly unwrapping
    sortedLiftEvents = dailyMaximums.sorted(by: { [=11=]?.date.compare((?.date)!) == .orderedAscending }) as! [LiftEvent]

    let intervalBetweenDates: TimeInterval = 3600 * 24 // 3600 = 1 hour
    let startDate = (sortedLiftEvents.first?.date)! - intervalBetweenDates
    let lastDate = sortedLiftEvents.last?.date

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "MMM d"
    let dates:[Date] = intervalDates(from: startDate, to: lastDate!, with: intervalBetweenDates)

    days = dates.map {dateFormatter.string(from: [=11=])}

    generateLineData()

}

最后,这是 generateLineData 方法:

func fetchData() {

    chartView.data = nil

    let liftName = UserDefaults.selectedLiftForChart()
    let liftEvents = dataManager.fetchLiftsEventsOfTypeByName(liftName)

    guard liftEvents.count > 0 else {
        chartView.noDataText = "There's no \(liftName) data to display"
        shouldHideData = true

        return }

    // put them into a Dictionary grouped by each unique day
    let groupedEvents = Dictionary(grouping: liftEvents, by: { floor([=11=].date.timeIntervalSince1970 / 86400) })

    // grab the maximum 1RM from each day
    let dailyMaximums = groupedEvents.map { .max(by: { [=11=].oneRepMax < .oneRepMax }) }

    // MARK: - TODO: Fix the silly unwrapping
    sortedLiftEvents = dailyMaximums.sorted(by: { [=11=]?.date.compare((?.date)!) == .orderedAscending }) as! [LiftEvent]

    let intervalBetweenDates: TimeInterval = 3600 * 24 // 3600 = 1 hour
    let startDate = (sortedLiftEvents.first?.date)! - intervalBetweenDates
    let lastDate = sortedLiftEvents.last?.date

    let dateFormatter = DateFormatter()
    dateFormatter.dateFormat = "MMM d"
    let dates:[Date] = intervalDates(from: startDate, to: lastDate!, with: intervalBetweenDates)

    days = dates.map {dateFormatter.string(from: [=11=])}

    generateLineData()

}

我试过将 chartView.setVisibleXRangeMaximum(7) 放在设置图表数据的方法中,并验证每次呈现图表时 chartView.visibleXRange 都是 7,但这没有什么不同。我还确保在为图表设置数据后设置最大值 XRange

还有什么我可以尝试的吗?或者这可能是一个尚未修复的错误?

谢谢

嗯,我终于明白了。我通过阅读文档知道,在将图表数据传递给图表后,必须设置一些属性。尚不完全清楚哪些属性,但通过大量调试和消除过程,我确定是 xAxis 属性需要在数据更改时重置。

现在,当数据改变时,我调用我的新函数:

func resetxAxis() {
    let xAxis = chartView.xAxis
    xAxis.labelPosition = .bottom
    xAxis.axisMinimum = 0
    xAxis.granularity = 1
    xAxis.axisLineWidth = 5
    xAxis.valueFormatter = self
}

这已经在我的 viewDidLoad 方法中,所以我用它制作了上面的方法,并且可以在需要时随时调用它。