How to change line and fill color of MPAndroidChart line chart based on if y axis value is positive or negative

泄露秘密 提交于 2020-12-13 03:08:25

问题


Was wondering if it is possible to change the line and fill color for the line chart based on if the y-axis values are positive or negative. An example of it is below

Below is what i could achieve with the following code

    private fun setUpLineChart() {
        val lineData = getDataSet()
        view.lineChart.apply {
            data = lineData
            description.isEnabled = false
            setScaleEnabled(false)
            setTouchEnabled(false)
            legend.isEnabled = false
            axisLeft.apply {
                setDrawLabels(false)
                setDrawGridLines(false)
                setDrawAxisLine(false)
                spaceBottom = 30f
            }
            axisRight.apply {
                setDrawLabels(false)
                setDrawGridLines(false)
                setDrawAxisLine(false)
            }
            xAxis.apply {
                setDrawLabels(false)
                setDrawGridLines(false)
                setDrawAxisLine(false)
            }
            animateXY(700, 1000, Easing.EaseInOutQuad)
        }
    }

    private fun getDataSet(): LineData {
        val entries = mutableListOf<Entry>()
        val dataList = listOf(1, 20, -20, 33, 54, 7, -18, 2)

        dataList.forEachIndexed { index, element ->
            entries.add(Entry(index.toFloat(), element.toFloat()))
        }

        val dataSet = LineDataSet(entries, "")
        dataSet.apply {
            setDrawCircles(false)
            valueTextSize = 0f
            lineWidth = 3f
            mode = LineDataSet.Mode.HORIZONTAL_BEZIER
            color = ContextCompat.getColor(view.context, R.color.colorOnSurface)
            setDrawFilled(true)
            fillColor = ContextCompat.getColor(view.context, R.color.colorSurface2)
        }
        return LineData(dataSet)
    }

回答1:


The line and fill colors are bind to a specific LineDataSet. So to achieve the result you want according to the above example you have to separate your current dataSet into 4 LineDataSets (2 positive and 2 negative) and by doing this each one then can have its own fill and line colors and you are flexible to have as many colors you want for each dataSet. Of course you have to do your own logic to separate the positive LineDataSets from negative LineDataSets. I have modified your getDataSet() function to give you an example of how to achieve the separation of positive LineDataSets from negative LineDataSets each one having its own line and fill colors.

private fun getDataSet(): LineData? {
        val dataSets: MutableList<ILineDataSet> = ArrayList()
        val yArray = floatArrayOf(1f, 20f, -20f, 33f, 54f, 7f, -18f, 2f)
        var entries = ArrayList<Entry?>()
        var prevValueIsPositive = false
        var prevValueIsNegative = false
        val step = 1f
        for (i in yArray.indices) {
            val y = yArray[i]
            //positive y values
            if (y >= 0) {
                //we are changing to positive values so draw the current negative dataSets
                if (prevValueIsNegative) {
                    //calculate the common mid point between a positive and negative y
                    val midEntry = Entry(i.toFloat() - step / 2, 0f)
                    entries.add(midEntry)

                    //draw the current negative dataSet to Red color
                    dataSets.add(getLineDataSet(entries, android.R.color.holo_red_dark, android.R.color.holo_purple))

                    //and initialize a new DataSet starting from the above mid point Entry
                    entries = ArrayList()
                    entries.add(midEntry)
                    prevValueIsNegative = false
                }

                //we are already in a positive dataSet continue adding positive y values
                entries.add(Entry(i.toFloat(), y))
                prevValueIsPositive = true
                //not having any other positive-negative changes so add the remaining positive values in the final dataSet
                if (i == yArray.size - 1) {
                    dataSets.add(getLineDataSet(entries, android.R.color.holo_green_light, android.R.color.holo_orange_dark))
                }
            } else {
                //we are changing to negative values so draw the current positive dataSets
                if (prevValueIsPositive) {
                    //calculate the common mid point between a positive and negative y
                    val midEntry = Entry(i.toFloat() - step / 2, 0f)
                    entries.add(midEntry)

                    //draw the current positive dataSet to Green color
                    dataSets.add(getLineDataSet(entries, android.R.color.holo_green_light, android.R.color.holo_orange_dark))

                    //and initialize a new DataSet starting from the above mid point Entry
                    entries = ArrayList()
                    entries.add(midEntry)
                    prevValueIsPositive = false
                }

                //we are already in a negative dataSet continue adding negative y values
                entries.add(Entry(i.toFloat(), y))
                prevValueIsNegative = true
                //not having any other positive-negative changes so add the remaining negative values in the final dataSet
                if (i == yArray.size - 1) {
                    dataSets.add(getLineDataSet(entries, android.R.color.holo_red_dark, android.R.color.holo_purple))
                }
            }
        }
        return LineData(dataSets)
    }

with the usage of the below helper function to prepare a new LineDataSet with its specified line and fill colors:

private fun getLineDataSet(entries: ArrayList<Entry?>, fillColor: Int, lineColor: Int): LineDataSet {
        val dataSet = LineDataSet(entries, "")
        dataSet.setDrawCircles(false)
        dataSet.valueTextSize = 0f
        dataSet.lineWidth = 3f
        dataSet.mode = LineDataSet.Mode.HORIZONTAL_BEZIER
        dataSet.color = ContextCompat.getColor(this, lineColor)
        dataSet.setDrawFilled(true)
        dataSet.fillColor = ContextCompat.getColor(this, fillColor)
        return dataSet
    }


来源:https://stackoverflow.com/questions/64089807/how-to-change-line-and-fill-color-of-mpandroidchart-line-chart-based-on-if-y-axi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!