问题
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