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

如何在Jetpack Compose的Vico柱状图中为正负值设置不同颜色

在Jetpack Compose的Vico柱状图中实现正负柱子差异化颜色及DynamicShader使用

一、实现正负柱子不同颜色

你需要替换原有的固定颜色配置,改用ColumnComponent的colorProvider根据柱子对应的数值动态返回颜色,具体修改如下:

  1. 替换原rememberLineComponent为rememberColumnComponent(柱状图需用ColumnComponent而非LineComponent),并配置颜色提供器:
rememberColumnComponent(
    thickness = 24.dp,
    shape = RoundedCornerShape(6.dp).toVicoShape(),
    colorProvider = { context, index, _ ->
        // 获取当前柱子对应的数值
        val value = context.model.columnSeries[0].values[index]
        if (value < 0) Color.Red else Color.Green
    }
)
  1. 更新rememberColumnCartesianLayer的series配置:
rememberColumnCartesianLayer(
    series = rememberColumnSeries(
        column = rememberColumnComponent(
            thickness = 24.dp,
            shape = RoundedCornerShape(6.dp).toVicoShape(),
            colorProvider = { context, index, _ ->
                val value = context.model.columnSeries[0].values[index]
                if (value < 0) Color.Red else Color.Green
            }
        )
    )
)

二、DynamicShader的使用

Vico支持通过ShaderBrush结合dynamicShader实现动态着色效果,比如给正负柱子添加渐变或随数值变化的动态颜色,示例如下:

  1. 创建动态Shader:
// 正柱子的绿色渐变Shader
val positiveShader = rememberDynamicShader { size ->
    LinearGradientShader(
        colors = listOf(Color.Green.copy(alpha = 0.7f), Color.Green),
        start = Offset(0f, 0f),
        end = Offset(0f, size.height)
    )
}

// 负柱子的红色渐变Shader
val negativeShader = rememberDynamicShader { size ->
    LinearGradientShader(
        colors = listOf(Color.Red, Color.Red.copy(alpha = 0.7f)),
        start = Offset(0f, 0f),
        end = Offset(0f, size.height)
    )
}
  1. 在ColumnComponent中使用ShaderBrush替代固定颜色:
rememberColumnComponent(
    thickness = 24.dp,
    shape = RoundedCornerShape(6.dp).toVicoShape(),
    brushProvider = { context, index, _ ->
        val value = context.model.columnSeries[0].values[index]
        if (value < 0) ShaderBrush(negativeShader) else ShaderBrush(positiveShader)
    }
)

完整修改后的CartesianChartHost代码

// 定义动态Shader
val positiveShader = rememberDynamicShader { size ->
    LinearGradientShader(
        colors = listOf(Color.Green.copy(alpha = 0.7f), Color.Green),
        start = Offset(0f, 0f),
        end = Offset(0f, size.height)
    )
}

val negativeShader = rememberDynamicShader { size ->
    LinearGradientShader(
        colors = listOf(Color.Red, Color.Red.copy(alpha = 0.7f)),
        start = Offset(0f, 0f),
        end = Offset(0f, size.height)
    )
}

CartesianChartHost(
    modifier = Modifier.height(250.dp),
    chart = rememberCartesianChart(
        rememberColumnCartesianLayer(
            series = rememberColumnSeries(
                column = rememberColumnComponent(
                    thickness = 24.dp,
                    shape = RoundedCornerShape(6.dp).toVicoShape(),
                    brushProvider = { context, index, _ ->
                        val value = context.model.columnSeries[0].values[index]
                        if (value < 0) ShaderBrush(negativeShader) else ShaderBrush(positiveShader)
                    }
                )
            )
        ),
        startAxis = rememberStartAxis(
            label = rememberAxisLabelComponent(color = Color.Black),
        ),
        bottomAxis = rememberBottomAxis(
            label = rememberAxisLabelComponent(color = Color.Black),
            valueFormatter = axisFormatter
        ),
    ),
    modelProducer = modelProducer
)

注意事项:

  • 确保使用的Vico版本支持brushProvider和dynamicShader(建议升级至最新稳定版)
  • 若需要更复杂的动态效果,可在rememberDynamicShader的lambda中根据柱子尺寸、数值等参数调整Shader配置

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 01:30:32