Reputation: 1450
I'm trying out @danielgindi's Charts framework to create a Line Chart but my data won't display on the chart:
I started with the CombinedChartViewController
demo because I wanted some of the features that it has. My plan was to remove the chart data types I didn't need and leave the LineChartData
.
Before making a final change, the data displayed properly:
Then, I changed the type of data
from CombinedChartData
to LineChartData
and assign the LineChartData
to chartView.data
instead of data.lineData
. As soon as I did this, the data stopped displaying.
I've compared by code to the LineChart1ViewController
code and don't see any material difference that could cause this. I've poured through the documentation and the issues on Github and looked through all of the related questions I could find on SO. I've confirmed that my data is ordered properly (as suggested) but it made no difference. And as I mentioned, that same data renders properly when using CombinedChartData
.
I've struggled with this for a couple of days and I'm out of ideas to try. Can anybody offer any ideas I haven't yet tried?
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($0.date.timeIntervalSince1970 / 86400) })
let maxEventsPerDay = groupedEvents.map { $1.max(by: { $0.oneRepMax < $1.oneRepMax }) }
// MARK: - Fix the silly unwrapping
sortedLiftEvents = maxEventsPerDay.sorted(by: { $0?.date.compare(($1?.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: $0)}
}
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]
}
}
}
}
The ChartDataEntry's in entries
look like this:
▿ 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
Upvotes: 1
Views: 1590
Reputation: 5032
Your view controller code is perfectly okay with my code. Probably you have a class reference problem:
Go to storyboard and change the chart view class from "CombinedChartView" to "LineChartView".
Upvotes: 3