Android - Fill different colors between two lines using MPAndroidChart
Asked Answered
D

3

3

following this (Android - Fill the color between two lines using MPAndroidChart) answer I was able to fill with color the space between two lines using AndroidMPChart library.

But now I want to customize the filling color to have:

  • the areas above the boundarySet filled with blue color;

  • the areas below the boundarySet filled with green color.

Like in the following screenshot (please note that the blue line is a lineSet, so it could be that it is not a limit line):

enter image description here

I would like to customize the line color of the chart, setting it as the filling:

  • blue color for the line above the boundarySet;

  • green color for the line below the boundary set.

Is it possible? I'm not able to find anything similar in the examples using MPAndroidChart.

Thank you!

Donniedonnish answered 29/5, 2019 at 14:11 Comment(3)
I think You can draw two lines with different color. In first line(add values greater than 20) set blue color and In second line add values less than 20 set color green.Pontianak
Could you provide me an example? It is not clear to me how to build the two lines having the LineDataSetsDonniedonnish
@Donniedonnish have you got the any solution.Can you tell me how to do it?Panada
L
0

you can try to override the drawLinear in LineChartRender

Lindemann answered 31/5, 2019 at 16:5 Comment(0)
D
0

This has worked for me:

dataSet.setFillFormatter(new DefaultFillFormatter() {
    @Override
    public float getFillLinePosition(ILineDataSet dataSet, LineDataProvider dataProvider) {
        return 22500;// its value of midel Y line 
    }
});
Deem answered 2/10, 2019 at 12:30 Comment(0)
T
0

I've done this with this custom chart render) I use colors from line here, but you can use other colors. Change your colors here :drawFilledPath(c, filled, dataSet.colors[index], dataSet.fillAlpha)

class CustomLineChartRender(
lineDataProvider: LineDataProvider,
chartAnimator: ChartAnimator,
port: ViewPortHandler

) : LineChartRenderer(lineDataProvider, chartAnimator, port) { override fun drawLinearFill( c: Canvas?, dataSet: ILineDataSet?, trans: Transformer?, bounds: XBounds? ) { val filled = mGenerateFilledPathBuffer

    val startingIndex = bounds!!.min
    val endingIndex = bounds!!.range + bounds!!.min
    val indexInterval = 1

    var currentStartIndex = 0
    var currentEndIndex = indexInterval
    var iterations = 0

    do {
        currentStartIndex = startingIndex + iterations * indexInterval
        currentEndIndex = currentStartIndex + indexInterval
        currentEndIndex = if (currentEndIndex > endingIndex) endingIndex else currentEndIndex
        if (currentStartIndex <= currentEndIndex) {
            generateFilledPath(dataSet!!, currentStartIndex, currentEndIndex, filled)
            trans!!.pathValueToPixel(filled)
            val drawable = dataSet.fillDrawable
            if (drawable != null) {
                drawFilledPath(c, filled, drawable)
            } else {
                val index = startingIndex + iterations
                drawFilledPath(c, filled, dataSet.colors[index], dataSet.fillAlpha)
            }
        }
        iterations++
    } while (currentStartIndex <= currentEndIndex)

}

private fun generateFilledPath(
    dataSet: ILineDataSet,
    startIndex: Int,
    endIndex: Int,
    outputPath: Path
) {
    val fillMin = dataSet.fillFormatter.getFillLinePosition(dataSet, mChart)
    val phaseY = mAnimator.phaseY
    val isDrawSteppedEnabled = dataSet.mode == LineDataSet.Mode.STEPPED
    outputPath.reset()
    val entry = dataSet.getEntryForIndex(startIndex)
    outputPath.moveTo(entry.x, fillMin)
    outputPath.lineTo(entry.x, entry.y * phaseY)

    // create a new path
    var currentEntry: Entry? = null
    var previousEntry = entry
    for (x in startIndex + 1..endIndex) {
        currentEntry = dataSet.getEntryForIndex(x)
        if (isDrawSteppedEnabled) {
            outputPath.lineTo(currentEntry.x, previousEntry!!.y * phaseY)
        }
        outputPath.lineTo(currentEntry.x, currentEntry.y * phaseY)
        previousEntry = currentEntry
    }

    // close up
    if (currentEntry != null) {
        outputPath.lineTo(currentEntry.x, fillMin)
    }
    outputPath.close()
}

}

Trounce answered 11/5, 2022 at 12:40 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.