为什么我的折线图不显示其数据?
Why doesn't my line chart display its data?
我正在尝试使用@danielgindi 的图表框架来创建折线图,但我的数据不会显示在图表上:
我从 CombinedChartViewController
演示开始,因为我想要它具有的一些功能。我的计划是删除我不需要的图表数据类型并保留 LineChartData
.
最后修改之前,数据显示正常:
然后,我将 data
的类型从 CombinedChartData
更改为 LineChartData
并将 LineChartData
分配给 chartView.data
而不是 data.lineData
.我一这样做,数据就停止显示了。
我按代码与 LineChart1ViewController
代码进行了比较,没有发现任何可能导致此问题的 material 差异。我已经仔细阅读了 Github 上的文档和问题,并查看了我可以在 SO 上找到的所有相关问题。我已确认我的数据已正确排序 (),但没有任何区别。正如我提到的,相同的数据在使用 CombinedChartData
时可以正确呈现。
我已经为此苦苦挣扎了几天,但我没有想法可以尝试。谁能提供我尚未尝试过的任何想法?
import UIKit
import Charts
var shouldHideData: Bool = false
class ChartViewController: UIViewController, ChartViewDelegate {
@IBOutlet var chartView: LineChartView!
fileprivate let dataManager = CoreDataHelper()
fileprivate var sortedLiftEvents: [LiftEvent] = []
var days: [String]? = []
override func viewDidLoad() {
super.viewDidLoad()
self.title = "1RM"
chartView.delegate = self
chartView.chartDescription?.enabled = false
let leftAxis = chartView.leftAxis
leftAxis.axisMinimum = 0
leftAxis.labelTextColor = NSUIColor.white
let xAxis = chartView.xAxis
xAxis.labelPosition = .bottom
xAxis.axisMinimum = 0
xAxis.granularity = 1
xAxis.valueFormatter = self
xAxis.labelTextColor = NSUIColor.white
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()
self.updateChartData()
chartView.configureDefaults()
chartView.setVisibleXRangeMaximum(5)
view.backgroundColor = UIColor(hexString: "232B35")
}
private func fetchData() {
let liftEventTypeUuid = "98608870-E3CE-476A-B1E4-018D2AE4BDBF"
// get all Bench Press events
let liftEvents = dataManager.fetchLiftsEventsOfType(liftEventTypeUuid)
// put them into a Dictionary grouped by each unique day
let groupedEvents = Dictionary(grouping: liftEvents, by: { floor([=10=].date.timeIntervalSince1970 / 86400) })
let maxEventsPerDay = groupedEvents.map { .max(by: { [=10=].oneRepMax < .oneRepMax }) }
// MARK: - Fix the silly unwrapping
sortedLiftEvents = maxEventsPerDay.sorted(by: { [=10=]?.date.compare((?.date)!) == .orderedAscending }) as! [LiftEvent]
/// 3600 = 1 hour
/// 1 day
let startingDate = sortedLiftEvents.first?.date
let endDate = sortedLiftEvents.last?.date
let intervalBetweenDates:TimeInterval = 3600 * 24
let dates:[Date] = intervalDates(from: startingDate!, to: endDate!, with: intervalBetweenDates)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM d"
days = dates.map{dateFormatter.string(from: [=10=])}
}
func updateChartData() {
if shouldHideData {
chartView.data = nil
return
}
self.setChartData()
}
func setChartData() {
generateLineData()
}
func generateLineData() {
let entries = sortedLiftEvents.enumerated().map { (arg) -> ChartDataEntry in
let (index, liftEvent) = arg
return ChartDataEntry(x: Double(index), y: liftEvent.oneRepMax.value)
}
// style the line to be drawn
let set = LineChartDataSet(values: entries, label: "Line DataSet")
set.setColor(UIColor(hexString: "768DAA"))
set.lineWidth = 1.5
set.setCircleColor((UIColor(hexString: "768DAA")))
set.circleHoleColor = UIColor(red: 35/255, green: 43/255, blue: 53/255, alpha: 1)
set.circleRadius = 4
set.circleHoleRadius = 2
// set.fillColor = (UIColor(hexString: "F20B27"))
set.mode = .linear
set.drawValuesEnabled = true
set.valueFont = .systemFont(ofSize: 10)
set.valueTextColor = UIColor(red: 240/255, green: 238/255, blue: 70/255, alpha: 1)
set.axisDependency = .left
let data = LineChartData(dataSet: set)
chartView.data = data
}
func intervalDates(from startingDate:Date, to endDate:Date, with interval:TimeInterval) -> [Date] {
guard interval > 0 else { return [] }
var dates:[Date] = []
var currentDate = startingDate
while currentDate <= endDate {
currentDate = currentDate.addingTimeInterval(interval)
dates.append(currentDate)
}
return dates
}
}
extension ChartViewController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
guard let days = days else { return "" }
return days[Int(value) % days.count]
}
}
}
}
entries
中的 ChartDataEntry 如下所示:
▿ 0 : ChartDataEntry, x: 0.0, y 209.0
▿ 1 : ChartDataEntry, x: 1.0, y 209.0
▿ 2 : ChartDataEntry, x: 2.0, y 246.0
▿ 3 : ChartDataEntry, x: 3.0, y 233.333333333333
▿ 4 : ChartDataEntry, x: 4.0, y 220.0
▿ 5 : ChartDataEntry, x: 5.0, y 234.0
▿ 6 : ChartDataEntry, x: 6.0, y 220.0
▿ 7 : ChartDataEntry, x: 7.0, y 240.0
▿ 8 : ChartDataEntry, x: 8.0, y 227.5
▿ 9 : ChartDataEntry, x: 9.0, y 239.166666666667
▿ 10 : ChartDataEntry, x: 10.0, y 234.666666666667
...
▿ 90 : ChartDataEntry, x: 90.0, y 220.0
▿ 91 : ChartDataEntry, x: 91.0, y 238.0
▿ 92 : ChartDataEntry, x: 92.0, y 234.0
▿ 93 : ChartDataEntry, x: 93.0, y 220.0
▿ 94 : ChartDataEntry, x: 94.0, y 240.0
▿ 95 : ChartDataEntry, x: 95.0, y 226.666666666667
▿ 96 : ChartDataEntry, x: 96.0, y 227.5
▿ 97 : ChartDataEntry, x: 97.0, y 239.166666666667
▿ 98 : ChartDataEntry, x: 98.0, y 234.666666666667
▿ 99 : ChartDataEntry, x: 99.0, y 240.0
▿ 100 : ChartDataEntry, x: 100.0, y 222.0
您的视图控制器代码与我的代码完全一致。可能你有一个 class 引用问题:
转到 Storyboard 并将图表视图 class 从“CombinedChartView”更改为“LineChartView”。
我正在尝试使用@danielgindi 的图表框架来创建折线图,但我的数据不会显示在图表上:
我从 CombinedChartViewController
演示开始,因为我想要它具有的一些功能。我的计划是删除我不需要的图表数据类型并保留 LineChartData
.
最后修改之前,数据显示正常:
然后,我将 data
的类型从 CombinedChartData
更改为 LineChartData
并将 LineChartData
分配给 chartView.data
而不是 data.lineData
.我一这样做,数据就停止显示了。
我按代码与 LineChart1ViewController
代码进行了比较,没有发现任何可能导致此问题的 material 差异。我已经仔细阅读了 Github 上的文档和问题,并查看了我可以在 SO 上找到的所有相关问题。我已确认我的数据已正确排序 (CombinedChartData
时可以正确呈现。
我已经为此苦苦挣扎了几天,但我没有想法可以尝试。谁能提供我尚未尝试过的任何想法?
import UIKit
import Charts
var shouldHideData: Bool = false
class ChartViewController: UIViewController, ChartViewDelegate {
@IBOutlet var chartView: LineChartView!
fileprivate let dataManager = CoreDataHelper()
fileprivate var sortedLiftEvents: [LiftEvent] = []
var days: [String]? = []
override func viewDidLoad() {
super.viewDidLoad()
self.title = "1RM"
chartView.delegate = self
chartView.chartDescription?.enabled = false
let leftAxis = chartView.leftAxis
leftAxis.axisMinimum = 0
leftAxis.labelTextColor = NSUIColor.white
let xAxis = chartView.xAxis
xAxis.labelPosition = .bottom
xAxis.axisMinimum = 0
xAxis.granularity = 1
xAxis.valueFormatter = self
xAxis.labelTextColor = NSUIColor.white
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()
self.updateChartData()
chartView.configureDefaults()
chartView.setVisibleXRangeMaximum(5)
view.backgroundColor = UIColor(hexString: "232B35")
}
private func fetchData() {
let liftEventTypeUuid = "98608870-E3CE-476A-B1E4-018D2AE4BDBF"
// get all Bench Press events
let liftEvents = dataManager.fetchLiftsEventsOfType(liftEventTypeUuid)
// put them into a Dictionary grouped by each unique day
let groupedEvents = Dictionary(grouping: liftEvents, by: { floor([=10=].date.timeIntervalSince1970 / 86400) })
let maxEventsPerDay = groupedEvents.map { .max(by: { [=10=].oneRepMax < .oneRepMax }) }
// MARK: - Fix the silly unwrapping
sortedLiftEvents = maxEventsPerDay.sorted(by: { [=10=]?.date.compare((?.date)!) == .orderedAscending }) as! [LiftEvent]
/// 3600 = 1 hour
/// 1 day
let startingDate = sortedLiftEvents.first?.date
let endDate = sortedLiftEvents.last?.date
let intervalBetweenDates:TimeInterval = 3600 * 24
let dates:[Date] = intervalDates(from: startingDate!, to: endDate!, with: intervalBetweenDates)
let dateFormatter = DateFormatter()
dateFormatter.dateFormat = "MMM d"
days = dates.map{dateFormatter.string(from: [=10=])}
}
func updateChartData() {
if shouldHideData {
chartView.data = nil
return
}
self.setChartData()
}
func setChartData() {
generateLineData()
}
func generateLineData() {
let entries = sortedLiftEvents.enumerated().map { (arg) -> ChartDataEntry in
let (index, liftEvent) = arg
return ChartDataEntry(x: Double(index), y: liftEvent.oneRepMax.value)
}
// style the line to be drawn
let set = LineChartDataSet(values: entries, label: "Line DataSet")
set.setColor(UIColor(hexString: "768DAA"))
set.lineWidth = 1.5
set.setCircleColor((UIColor(hexString: "768DAA")))
set.circleHoleColor = UIColor(red: 35/255, green: 43/255, blue: 53/255, alpha: 1)
set.circleRadius = 4
set.circleHoleRadius = 2
// set.fillColor = (UIColor(hexString: "F20B27"))
set.mode = .linear
set.drawValuesEnabled = true
set.valueFont = .systemFont(ofSize: 10)
set.valueTextColor = UIColor(red: 240/255, green: 238/255, blue: 70/255, alpha: 1)
set.axisDependency = .left
let data = LineChartData(dataSet: set)
chartView.data = data
}
func intervalDates(from startingDate:Date, to endDate:Date, with interval:TimeInterval) -> [Date] {
guard interval > 0 else { return [] }
var dates:[Date] = []
var currentDate = startingDate
while currentDate <= endDate {
currentDate = currentDate.addingTimeInterval(interval)
dates.append(currentDate)
}
return dates
}
}
extension ChartViewController: IAxisValueFormatter {
func stringForValue(_ value: Double, axis: AxisBase?) -> String {
guard let days = days else { return "" }
return days[Int(value) % days.count]
}
}
}
}
entries
中的 ChartDataEntry 如下所示:
▿ 0 : ChartDataEntry, x: 0.0, y 209.0
▿ 1 : ChartDataEntry, x: 1.0, y 209.0
▿ 2 : ChartDataEntry, x: 2.0, y 246.0
▿ 3 : ChartDataEntry, x: 3.0, y 233.333333333333
▿ 4 : ChartDataEntry, x: 4.0, y 220.0
▿ 5 : ChartDataEntry, x: 5.0, y 234.0
▿ 6 : ChartDataEntry, x: 6.0, y 220.0
▿ 7 : ChartDataEntry, x: 7.0, y 240.0
▿ 8 : ChartDataEntry, x: 8.0, y 227.5
▿ 9 : ChartDataEntry, x: 9.0, y 239.166666666667
▿ 10 : ChartDataEntry, x: 10.0, y 234.666666666667
...
▿ 90 : ChartDataEntry, x: 90.0, y 220.0
▿ 91 : ChartDataEntry, x: 91.0, y 238.0
▿ 92 : ChartDataEntry, x: 92.0, y 234.0
▿ 93 : ChartDataEntry, x: 93.0, y 220.0
▿ 94 : ChartDataEntry, x: 94.0, y 240.0
▿ 95 : ChartDataEntry, x: 95.0, y 226.666666666667
▿ 96 : ChartDataEntry, x: 96.0, y 227.5
▿ 97 : ChartDataEntry, x: 97.0, y 239.166666666667
▿ 98 : ChartDataEntry, x: 98.0, y 234.666666666667
▿ 99 : ChartDataEntry, x: 99.0, y 240.0
▿ 100 : ChartDataEntry, x: 100.0, y 222.0
您的视图控制器代码与我的代码完全一致。可能你有一个 class 引用问题:
转到 Storyboard 并将图表视图 class 从“CombinedChartView”更改为“LineChartView”。