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

标签 swift ios-charts

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

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

1rm_normal

但是如果我在默认选择没有任何数据时转到这个 View Controller ,然后选择一个有数据的项目,它看起来像这样:

1) 继续:

1rm_nodatamessage

2) 然后选择一个有数据的项目:

1rm_squished

当然 viewDidLoad 在我转到 View Controller 时被调用,只要默认选择在我转到它时有数据,我就可以选择另一个有数据或没有数据的项目图表将继续正确呈现。所以差异似乎在 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($0.date.timeIntervalSince1970 / 86400) })

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

    // MARK: - TODO: Fix the silly unwrapping
    sortedLiftEvents = dailyMaximums.sorted(by: { $0?.date.compare(($1?.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: $0)}

    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($0.date.timeIntervalSince1970 / 86400) })

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

    // MARK: - TODO: Fix the silly unwrapping
    sortedLiftEvents = dailyMaximums.sorted(by: { $0?.date.compare(($1?.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: $0)}

    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 方法中,所以我用它制作了上面的方法,并且可以在需要时随时调用它。

关于swift - 图表的折线图无法正确呈现折线图,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49798279/

相关文章:

swift - 在 OSX 应用程序上运行测试时为 "Message from debugger: unable to attach"

ios - 游戏中的 SWIFT AVAudioPlayer 多个场景,停止不工作

swift - 在后台运行一个任务,在 Swift/iOS8 中从 MPMedia 框架切换歌曲长达 100 分钟

ios - TableView 单元格选择事件未触发

ios - 检查是否使用 QuickAction 打开了 ViewController

ios - 水平条形图 Swift

ios - 带有新 ios-charts 框架新版本的条形图

swift - ScrollView 中的 IOS 图表

ios - 动画自动布局约束不起作用

arrays - Swift 检查数组是否包含在另一个数组中