图表中的非填充条形问题:为什么颜色显示不正确?

问题描述 投票:0回答:1

我面临着条形图的问题,其中条形未正确填充指定的颜色。相反,它们看起来是空的。我尝试了各种方法来设置栏的自定义颜色,但似乎都没有按预期工作。

private fun showEnergy() {
val list = listOf(
        Triple("23-5-2024", 2010, 4.91),
        Triple("22-5-2024", 960, 13.62),
        Triple("21-5-2024", 5642, 2.0),
        Triple("20-5-2024", 1464, 4.85)
    )
        constraintLayoutStatisticsData.removeAllViews()
        constraintLayoutStatisticsData.addView(energyLayout)
        barChart = constraintLayoutStatisticsData.findViewById(R.id.barChart)
        val maxValue=10000f
        setupBarChart(maxValue)
        val currentDate = Date()
        // Create a list of dates for the last 30 days
        val dates = ArrayList<Date>()
        val calendar = Calendar.getInstance()
        for (i in 0 until 6) {
            calendar.time = currentDate
            calendar.add(Calendar.DAY_OF_MONTH, -i)
            dates.add(calendar.time)
        }
        dates.reverse()
        // Create a list of values, adding 0 for missing dates
        val firstBarEntries = ArrayList<BarEntry>()
        val secondBarEntries = ArrayList<BarEntry>()
        val barWidth = 0.26f
        val groupSpace = 0.32f
        val barSpace = 0.08f
        val dateFormat = SimpleDateFormat("d.M.yy", Locale.getDefault())
        for (date in dates) {
            val formattedDate = dateFormat.format(date)
            val value = list.find { it.first == formattedDate }?.second ?: 0
            firstBarEntries.add(BarEntry(date.time.toFloat()- barWidth / 2, value.toFloat()))
            val value2 = 4000f
            firstBarEntries.add(BarEntry(date.time.toFloat()- barWidth / 2, value2.toFloat()))
        }

        val firstDataSet = BarDataSet(firstBarEntries, "")
        firstDataSet.color=ContextCompat.getColor(constraintLayoutStatisticsData.context, R.color.grey)

        val secondDataSet = BarDataSet(secondBarEntries, "")

        val customColors = mutableListOf<Int>()
        for (i in list.indices) {
            val ratio = list[i].second / 4000f
            val color = when {
                ratio >= 0.85 && ratio <= 1.15 -> ContextCompat.getColor(constraintLayoutStatisticsData.context, R.color.green)
                ratio < 0.85 -> ContextCompat.getColor(constraintLayoutStatisticsData.context, R.color.orange)
                else -> ContextCompat.getColor(constraintLayoutStatisticsData.context, R.color.red)
            }
            customColors.add(color)
        }
        firstDataSet.setDrawValues(false)
        secondDataSet.setDrawValues(false)
        secondDataSet.setColors(customColors)
        val dataSet = listOf(firstDataSet, secondDataSet)

        // Create a BarData object and set data sets
        val barData = BarData(dataSet)
        barData.barWidth = barWidth
        val xAxis = barChart.xAxis
        xAxis.axisMinimum = -0.5f
        xAxis.axisMaximum = list.size - 0.5f
        xAxis.valueFormatter = object : ValueFormatter() {
            private val dateFormat = SimpleDateFormat("dd.MM", Locale.getDefault())

            override fun getFormattedValue(value: Float): String {
                val index = value.toInt()
                return if (index >= 0 && index < dates.size) {
                    dateFormat.format(dates[index])
                } else {
                    ""
                }
            }
        }
        barChart.axisLeft.valueFormatter = object : ValueFormatter() {
            override fun getFormattedValue(value: Float): String {
                // Replace commas with spaces
                val formattedValue = value.toInt().toString().replace(',', ' ')

                // Return the formatted value as a string
                return formattedValue
            }
        }
        
        // Set the chart data
        barChart.data = barData

        // Update chart
        barChart.invalidate()

    }

private fun setupBarChart(maxValue: Float) {
        barChart.setDrawBarShadow(false)
        barChart.description.isEnabled = false
        barChart.setMaxVisibleValueCount(60)
        barChart.setPinchZoom(false)
        barChart.setDrawGridBackground(false)
        val xAxis = barChart.xAxis
        xAxis.setDrawGridLines(false)
        xAxis.position = XAxis.XAxisPosition.BOTTOM
        xAxis.textColor = ContextCompat.getColor(constraintLayoutStatisticsData.context, R.color.text)
        xAxis.granularity = 1f

        val yAxisLeft = barChart.axisLeft
        yAxisLeft.setDrawAxisLine(false)
        yAxisLeft.textColor = ContextCompat.getColor(constraintLayoutStatisticsData.context, R.color.text)
        val minValue = 0f
        val labelCount = 5
        val interval = Math.ceil((maxValue - minValue) / (labelCount - 1).toDouble()).toFloat()
        yAxisLeft.axisMinimum = minValue
        yAxisLeft.axisMaximum = maxValue
        yAxisLeft.setGranularity(interval)
        yAxisLeft.setLabelCount(labelCount, true)
        yAxisLeft.gridLineWidth = 2f
        barChart.axisRight.isEnabled = false
        barChart.legend.isEnabled = false
    }
 

我也尝试过使用ARGB值和渐变,但结果仍然相同。这些条只是拒绝显示指定的颜色。

有人遇到过类似的条形图问题吗?什么可能导致这个问题?是否有我可能缺少的特定配置或设置?

任何帮助或建议将不胜感激。预先感谢您!

它需要像这样:[带有颜色的条形](https://i.sstatic.net/Q29koAnZ.png) 但它是这样的: a在此输入图像描述

java android bar-chart visualization mpandroidchart
1个回答
0
投票

这里有几个问题:

  1. 您将日期字符串格式化为 dd-m-yyyy,但正在使用 d.m.yy 格式进行搜索

  2. 您的条形 x 位置设置不一致。当您创建

    BarEntry
    列表时,您将根据实际日期设置 x 值

firstBarEntries.add(BarEntry(date.time.toFloat()- barWidth / 2, value.toFloat()))

但是当您设置 x 轴时,它是根据原始数据列表中的索引设置的

xAxis.axisMinimum = -0.5f
xAxis.axisMaximum = list.size - 0.5f

所以你的条形图远远超出了 x 范围。您需要将条形的 x 值更改为基于索引,并确保使用“日期”列表大小而不是

list
大小,因为它们可能不同。您还可以使用预制的
IndexAxisValueFormatter

稍微简化 x 轴
  1. 您需要按照

    此答案
    中所述致电barChart.groupBars

  2. 您从未将任何数据放入

    secondBarEntries
    - 我认为这是一个错字。

结合所有这些,您的代码的以下修改版本似乎可以按您的预期工作:

override fun onCreate(savedInstanceState: Bundle?) {
    super.onCreate(savedInstanceState)
    setContentView(R.layout.activity_main)

    val barChart = findViewById<BarChart>(R.id.chart)

    val list = listOf(
        Triple("23-05-2024", 2010, 4.91),
        Triple("22-05-2024", 960, 13.62),
        Triple("21-05-2024", 5642, 2.0),
        Triple("20-05-2024", 1464, 4.85)
    )

    val maxValue=10000f
    setupBarChart(barChart, maxValue)

    // Create a list of dates
    val dates = ArrayList<Date>()
    val calendar = Calendar.getInstance()
    for (i in 0 until 6) {
        calendar.set(2024,4,19) // months are 0-based
        calendar.add(Calendar.DAY_OF_MONTH, i)
        dates.add(calendar.time)
    }

    // pre-format a list of x axis labels to use
    val xDateFormat = SimpleDateFormat("dd.MM", Locale.getDefault())
    val xAxisLabels = dates.map { xDateFormat.format(it) }

    // Create a list of values, adding 0 for missing dates
    val firstBarEntries = ArrayList<BarEntry>()
    val secondBarEntries = ArrayList<BarEntry>()
    val lookupDateFormat = SimpleDateFormat("dd-MM-yyyy", Locale.getDefault())
    for (i in dates.indices) {
        val formattedDate = lookupDateFormat.format(dates[i])
        val value = list.find { it.first == formattedDate }?.second ?: 0
        firstBarEntries.add(BarEntry(i.toFloat(), value.toFloat()))
        val value2 = 4000f
        secondBarEntries.add(BarEntry(i.toFloat(), value2))
    }

    val firstDataSet = BarDataSet(firstBarEntries, "")
    firstDataSet.color = Color.GRAY

    val secondDataSet = BarDataSet(secondBarEntries, "")

    val customColors = mutableListOf<Int>()
    for (i in firstBarEntries.indices) {
        val ratio = firstBarEntries[i].y / secondBarEntries[i].y
        val color = when {
            ratio in 0.85..1.15 -> Color.GREEN
            ratio < 0.85 -> Color.MAGENTA
            else -> Color.RED
        }
        customColors.add(color)
    }
    firstDataSet.setDrawValues(false)
    secondDataSet.setDrawValues(false)
    secondDataSet.colors = customColors

    // ensure that groupSpace + 2*barSpace + 2*barWidth = 1
    val barWidth = 0.26f
    val barSpace = 0.08f
    val groupSpace = 1 - 2*barSpace - 2*barWidth

    // Create a BarData object and set data sets
    val barData = BarData(firstDataSet, secondDataSet)
    barData.barWidth = barWidth

    val xAxis = barChart.xAxis
    xAxis.axisMinimum = -0.5f
    xAxis.axisMaximum = dates.size.toFloat()
    xAxis.valueFormatter = IndexAxisValueFormatter(xAxisLabels)

    // Set the chart data
    barChart.data = barData
    barChart.groupBars(-0.5f, groupSpace, barSpace)

    // Update chart
    barChart.invalidate()
}

private fun setupBarChart(barChart: BarChart, maxValue: Float) {
    barChart.setDrawBarShadow(false)
    barChart.description.isEnabled = false
    barChart.setMaxVisibleValueCount(60)
    barChart.setPinchZoom(false)
    barChart.setDrawGridBackground(false)
    val xAxis = barChart.xAxis
    xAxis.setDrawGridLines(false)
    xAxis.position = XAxis.XAxisPosition.BOTTOM
    xAxis.textColor = Color.BLACK
    xAxis.granularity = 1f

    val yAxisLeft = barChart.axisLeft
    yAxisLeft.setDrawAxisLine(false)
    yAxisLeft.textColor = Color.BLACK
    val minValue = 0f
    val labelCount = 5
    val interval = Math.ceil((maxValue - minValue) / (labelCount - 1).toDouble()).toFloat()
    yAxisLeft.axisMinimum = minValue
    yAxisLeft.axisMaximum = maxValue
    yAxisLeft.setGranularity(interval)
    yAxisLeft.setLabelCount(labelCount, true)
    yAxisLeft.gridLineWidth = 2f
    barChart.axisRight.isEnabled = false
    barChart.legend.isEnabled = false
}

demo chart

© www.soinside.com 2019 - 2024. All rights reserved.