Search code examples
androiddatabaselinechartmpandroidchart

MPAndroidChart - hide missing data


I have a dataset that I would like to display using LineChart. However, the data is some times incomplete, and data is missing some timestamps.

Is there a way to not display a line when the LineChart (Y axis) has the value of, like 100000?

Is there a way to do this? Any idea are highly appreciated. Any other way to indicate "missing data" is also of interest.

I have tried to skip the datapoints, but then I get a straight line from previous datapoint to the next valid datapoint. I have tried putting "null", but MPAndroidChart insists on getting Float values I have tried setting value to "100000" and then trying to hide any data over 100. But I may have misunderstood the documentation ; "lineChart.setVisibleYRangeMaximum(100, YAxis.AxisDependency.LEFT);"


Update : I found something from 2016 Hide drawn line chart in MPAndroidChart Quote: Actually you can not "hide" a line in a linechart. But you can register your lines in different array and set the array you need in your chart and notify your chart to refresh with the good array. (The one with / without your line) This is simple and fast to set. Hope it helps.

Is this a thing, and will this work in 2023? And if so - please explain how this can be implemented.


Solution

  • The most robust way to handle gaps in your data set would be to just split the data into multiple discrete line segments, where each segment has no gaps.

    For example, if you had a list of values with gaps marked with Float.NaN values

    // Have some data set with some "missing" values (marked here with a NaN)
    // Plotting this by itself will also work to omit the missing points, but the lines
    // will also be completely missing
    val values = listOf(1f, 1.5f, Float.NaN, 2f, 1.8f, 1.85f, Float.NaN, 2f, 2.1f)
    

    You could split this into segments

    // Split the list into discrete segments of non-NaN entries
    val segments = values.withIndex().fold(mutableListOf(mutableListOf<Entry>())) { acc, a ->
        if( a.value.isNaN() ) acc += mutableListOf<Entry>()
        else acc.last().add(Entry(a.index.toFloat(), a.value))
        acc
    }
    

    then create a LineDataSet for each segment

    // generate a LineDataSet for each segment
    val dataSets = segments.mapNotNull { entries ->
        if (entries.isEmpty()) return@mapNotNull null
    
        val lineDataSet = LineDataSet(entries, "")
        lineDataSet.setDrawValues(false)
        lineDataSet.setDrawCircles(true)
        lineDataSet.setDrawCircleHole(false)
    
        lineDataSet.circleColors = listOf(Color.RED)
        lineDataSet.circleRadius = 5f
        lineDataSet.circleHoleRadius = 0f
        lineDataSet.color = Color.RED
        lineDataSet.lineWidth = 2f
        return@mapNotNull lineDataSet
    }
    

    and apply it to the chart

    // Add all the line segments to the chart
    chart.data = LineData(dataSets)
    chart.legend.isEnabled = false
    chart.description.isEnabled = false
    chart.xAxis.position = XAxis.XAxisPosition.BOTTOM
    

    to get the following result:

    line with gaps

    Note: You can also just plot the data with Float.NaN for the Y-value for the missing points, but because of what is probably a bug in MPAndroidChart the entire line disappears when you do that.