When creating a line chart from more than one data sets, the line chart only shows one of the data sets and when zooming or panning the chart it crashes with Fatal error: Can't form Range with upperBound < lowerBound.
If I create the line chart from one data set it works as expected.
This problem only occurs when the two datasets have completely different ranges of X values.
The code below should draw a chart with x ranging from 0 to 19 (i.e. 2 datasets). But it only draws the second dataset. The chart crashes if you pan or zoom it.
If I edit the code, replacing for x in (10..<20)
with for x in (0..<10)
, both datasets are correctly drawn and the chart does not crash.
To summarise: when adding two dataSets that have entries with different ranges of X coordinates the chart draws incorrectly and will crash.
Is there an iOS_charts API call needed to prevent this? How can I draw two datasets that do not have overlapping X-coordinates?
I've been able to produce the same crash when running code using this demo code if I modify it to create multiple datasets that have non-overlapping x-coordinates.
class ElevationChartViewController: UIViewController {
@IBOutlet var chartView: LineChartView!
override func viewDidLoad() {
super.viewDidLoad()
chartView.backgroundColor = .white
chartView.legend.enabled = false
chartView.maxVisibleCount = 20000
}
override func viewWillAppear(_ animated: Bool) {
super.viewWillAppear(animated)
let dataSets = createChartDataSets()
chartView.data = LineChartData(dataSets: dataSets)
}
}
func createChartDataSets() -> [LineChartDataSet] {
var dataSets = [LineChartDataSet]()
var entriesOne = [ChartDataEntry]()
var entriesTwo = [ChartDataEntry]()
var y = 0.0
for x in (0..<10) {
entriesOne.append( ChartDataEntry(x: Double(x), y: y))
y = y + 10
if y > 60 {y = 0.0}
}
dataSets.append(LineChartDataSet(entriesOne))
for x in (10..<20) {
entriesTwo.append( ChartDataEntry(x: Double(x), y: y))
y = y + 10
if y > 50 {y = 0.0}
}
dataSets.append(LineChartDataSet(entriesTwo))
return dataSets
}
Swift version: 5.4 Xcode 12.4 Observed running on a real iPhone 12 sw version 14.4 Charts v4.0.1
I have been facing a similar issue and this solution worked for me so far. Not sure about potential side effects that could arise from this. I have not tested with panning or zooming.
Subclass LineChartDataSet
and override entryIndex(x xValue:closestToY yValue:rounding)
copy and paste the super implementation, but remove the guard
statement at the top of the function
var closest = partitioningIndex { $0.x >= xValue }
guard closest < endIndex else { return -1 }
and replace with
var closest = partitioningIndex { $0.x >= xValue }
if closest >= endIndex {
closest = endIndex - 1
}