You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

柱状图无法正常填充指定颜色问题排查求助

柱状图无法填充颜色、显示为空的问题排查与修复

核心问题分析

  1. 日期格式不匹配:列表中的日期格式为"23-5-2024"(日-月-年),但代码中用SimpleDateFormat("d.M.yy")格式化日期,得到的是"23.5.24",两者无法匹配,导致所有数据值都为0,柱状条高度为0,自然显示为空。
  2. 数据集无数据:secondBarEntries从未添加任何BarEntry,对应的BarDataSet没有数据,不会渲染任何柱子。
  3. X轴范围与数据X值不匹配:你用时间戳(date.time.toFloat())作为柱状条的X值,但X轴的范围被设置为-0.5f到3.5f,远小于时间戳数值,导致所有柱子都不在可视区域内。
  4. 分组柱状图逻辑错误:手动调整X值实现分组的方式错误,且重复向firstBarEntries添加同X值的条目,造成数据混乱。

修复后的代码

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)

    // 生成最近6天的日期,用统一格式匹配list中的数据
    val currentDate = Date()
    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()

    val firstBarEntries = ArrayList<BarEntry>()
    val secondBarEntries = ArrayList<BarEntry>()
    val barWidth = 0.26f
    val groupSpace = 0.32f
    val barSpace = 0.08f
    // 改为和list匹配的日期格式:日-月-年
    val dateFormat = SimpleDateFormat("d-M-yyyy", Locale.getDefault())

    // 用索引作为X值,适配分组柱状图
    for ((index, date) in dates.withIndex()) {
        val formattedDate = dateFormat.format(date)
        // 匹配list中的日期
        val value = list.find { it.first == formattedDate }?.second ?: 0
        // 第一组柱子用索引作为X值
        firstBarEntries.add(BarEntry(index.toFloat(), value.toFloat()))
        // 第二组柱子添加数据,这里用示例值4000f,可根据需求替换
        val value2 = 4000f
        secondBarEntries.add(BarEntry(index.toFloat(), value2.toFloat()))
    }

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

    val secondDataSet = BarDataSet(secondBarEntries, "")
    secondDataSet.setDrawValues(false)

    // 生成对应所有日期的颜色列表(6个条目)
    val customColors = mutableListOf<Int>()
    for (date in dates) {
        val formattedDate = dateFormat.format(date)
        val item = list.find { it.first == formattedDate }
        val ratio = item?.second?.div(4000f) ?: 0f
        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)
    }
    secondDataSet.setColors(customColors)

    val dataSet = listOf(firstDataSet, secondDataSet)
    val barData = BarData(dataSet)
    barData.barWidth = barWidth

    // 设置分组柱状图的间距
    val groupCount = dates.size
    barData.groupBars(0f, groupSpace, barSpace)

    val xAxis = barChart.xAxis
    // X轴范围适配分组后的宽度
    xAxis.axisMinimum = 0f - barData.groupWidth(groupSpace, barSpace) / 2
    xAxis.axisMaximum = (groupCount - 1) + barData.groupWidth(groupSpace, barSpace) / 2
    xAxis.valueFormatter = object : ValueFormatter() {
        private val displayDateFormat = SimpleDateFormat("dd.MM", Locale.getDefault())

        override fun getFormattedValue(value: Float): String {
            val index = value.toInt()
            return if (index >= 0 && index < dates.size) {
                displayDateFormat.format(dates[index])
            } else {
                ""
            }
        }
    }

    barChart.axisLeft.valueFormatter = object : ValueFormatter() {
        override fun getFormattedValue(value: Float): String {
            return value.toInt().toString().replace(',', ' ')
        }
    }

    barChart.data = barData
    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
}

关键修复点说明

  • 统一了日期格式,确保list中的日期和格式化后的日期能正确匹配,获取到真实数据值;
  • 填充了secondBarEntries的数据集,确保第二个分组的柱子有数据可渲染;
  • 使用索引作为X值替代时间戳,配合barData.groupBars实现正确的分组柱状图布局;
  • 调整了X轴的范围,确保所有柱子都在可视区域内;
  • 生成了与日期数量匹配的颜色列表,避免颜色数量不足导致的渲染问题。

内容的提问来源于stack exchange,提问作者Liam Harpe

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.23 14:09:51