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

如何在Flutter中使用syncfusion_flutter_charts为图表添加阴影

如何为Syncfusion Flutter图表添加阴影效果

我在Flutter中使用syncfusion_flutter_charts组件展示图表,尝试用着色器实现阴影但没成功,想知道怎么给图表添加阴影效果。

现有代码

图表系列代码

List<ColumnSeries<ChartSampleData, String>> _getDefaultColumnSeries() {
  return <ColumnSeries<ChartSampleData, String>>[
    ColumnSeries<ChartSampleData, String>(
      dataSource: <ChartSampleData>[
        ChartSampleData(x: 'Jan', y: 200000),
        ChartSampleData(x: 'Feb', y: 100000),
        ChartSampleData(x: 'March', y: 50000),
        ChartSampleData(x: 'April', y: 0),
        ChartSampleData(x: 'May', y: 20000),
        ChartSampleData(x: 'June', y: 0),
      ],
      xValueMapper: (ChartSampleData sales, _) => sales.x,
      yValueMapper: (ChartSampleData sales, _) => sales.y,
      dataLabelSettings: const DataLabelSettings(
        textStyle: TextStyle(fontSize: 10),
      ),
      color: AppColors.bottomNavColor,
      borderRadius: const BorderRadius.vertical(top: Radius.circular(10)),
      onCreateShader: (ShaderDetails chartShaderDetails) {
        final shader = program!.fragmentShader();
        shader.setFloat(0, chartShaderDetails.rect.width);
        shader.setFloat(1, chartShaderDetails.rect.height);
        return shader;
      },
    )
  ];
}

着色器文件 graph_shader.frag

#include <flutter/runtime_effect.glsl>

precision mediump float;

uniform vec2 resolution;

out vec4 fragColor;

void main(){
   vec2 position = FlutterFragCoord().xy / resolution.xy;
   position.x -= resolution.x / resolution.y;
    
    vec3 color = vec3(0);
    fragColor = vec4(color, .7);
}

效果对比

当前效果

当前图表效果

期望效果

带阴影的图表


解决方案

方法1:使用Series自带阴影属性(最简便)

Syncfusion的ColumnSeries自带阴影相关属性,直接配置即可,不用写复杂的着色器:

ColumnSeries<ChartSampleData, String>(
  // 保留你原有的其他属性...
  elevation: 6, // 控制阴影强度,值越大阴影越明显
  shadowColor: Colors.grey.withOpacity(0.6), // 阴影颜色及透明度
)

设置后柱形会自动带有Material风格的阴影,和你期望的效果匹配。

方法2:容器包裹加整体阴影

如果需要给整个图表区域加阴影,而非单个柱形,可以把SfCartesianChart放在Container中,通过BoxDecoration设置阴影:

Container(
  margin: EdgeInsets.symmetric(horizontal: 16, vertical: 8),
  decoration: BoxDecoration(
    borderRadius: BorderRadius.circular(12),
    boxShadow: [
      BoxShadow(
        color: Colors.grey.withOpacity(0.4),
        spreadRadius: 1,
        blurRadius: 6,
        offset: Offset(0, 3), // 阴影的偏移方向和距离
      ),
    ],
  ),
  child: SfCartesianChart(
    series: _getDefaultColumnSeries(),
    // 其他图表配置
  ),
)

方法3:修复着色器实现自定义阴影

如果你一定要用着色器实现,需要修改着色器代码保留原柱形颜色,并添加阴影逻辑:

  1. 修改graph_shader.frag:
#include <flutter/runtime_effect.glsl>

precision mediump float;

uniform vec2 resolution;
uniform sampler2D inputImage; // 原柱形纹理

out vec4 fragColor;

void main() {
  vec2 uv = FlutterFragCoord().xy / resolution.xy;
  vec4 originalColor = texture(inputImage, uv);

  // 仅对不透明的柱形区域添加阴影
  if (originalColor.a > 0.0) {
    // 阴影偏移量(按需调整)
    vec2 shadowOffset = vec2(3.0, 3.0) / resolution.xy;
    vec4 shadow = texture(inputImage, uv - shadowOffset);
    shadow.rgb = vec3(0.2); // 阴影颜色
    shadow.a *= 0.5; // 阴影透明度

    // 混合阴影和原颜色
    fragColor = shadow + originalColor;
  } else {
    fragColor = originalColor;
  }
}
  1. 更新Dart代码中的onCreateShader:
onCreateShader: (ShaderDetails chartShaderDetails) {
  final shader = program!.fragmentShader();
  shader.setFloat(0, chartShaderDetails.rect.width);
  shader.setFloat(1, chartShaderDetails.rect.height);
  shader.setImageSampler(0, chartShaderDetails.sampler); // 传递原纹理
  return shader;
},

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.16 05:44:54