I've just implemented the library Charts (https://github.com/danielgindi/Charts) in a tableview, but I experience pretty heavy lag during scrolling, when my charts hold a lot of data.
I have a method inside the ChartTableViewCell where I draw the chart based on the data I pass and call from my viewcontroller.
func updateCell(chartData: ChartData) {
DispatchQueue.global(qos: .background).async {
print("This is run on the background queue")
self.readings = (readings != nil) ? readings!.readings : []
self.period = period
if (chartData.isKind(of: LineChartData.self)) {
data.lineData = chartData as! LineChartData
}
else if (chartData.isKind(of: BarChartData.self)) {
data.barData = chartData as! BarChartData
}
}
DispatchQueue.main.async {
self.chartView.data = data
}
}
In my tableViewController I call the function after parsing the data:
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let meta = chartMetas[indexPath.row]
let cell = tableView.dequeueReusableCell(withIdentifier: "chartCell", for: indexPath) as! ChartTableViewCell
cell.readings = currentReadings
cell.updateCell()
return cell
}
What did I miss? Since the view is lagging so hard when scrolling.
UPDATE:
I tried, as suggested, to prepare the chart data in the viewcontroller and pass it to the cell. However it seems like the problem in the resuseable cells, the lags appears when I scroll and a new cell enters the screen. How can I fix this? It is pretty annoying.
UPDATE 2: It looks like the Charts aren't supposed to be used in a tableview... https://github.com/danielgindi/Charts/issues/3395
To get a serious performance boost, you'll likely need to implement UITableViewDataSourcePrefecting
. By doing this, the table view will call into your delegate to let you know that a cell will be needed ahead of time. This will give your code a chance to prepare and render any data it needs.
From the documentation:
You use a prefetch data source object in conjunction with your table view’s data source to begin loading data for cells before the tableView(_:cellForRowAt:) data source method is called.The following steps are required to add a prefetch data source to your table view:
Create the table view and its data source.
Create an object that adopts the UITableViewDataSourcePrefetching protocol, and assign it to the prefetchDataSource property on the table view.
Initiate asynchronous loading of the data required for the cells at the specified index paths in your implementation of tableView(_:prefetchRowsAt:).
Prepare the cell for display using the prefetched data in your tableView(_:cellForRowAt:) data source method.
Cancel pending data load operations when the table view informs you that the data is no longer required in the tableView(_:cancelPrefetchingForRowsAt:) method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With