mcpField
F
flutter-chart

flutter-chart

github.com/entronad开发1.8k118 次安装35 周前更新
代码仓库

关于 flutter-chart

flutter-chart 是帮助开发者使用 Flutter 的 Graphic 库构建数据可视化的技能。它涵盖声明式图表配置和自定义渲染,可用于标准图表,也可扩展形状、提示框与标注。

主要功能

  1. 01配置声明式图表层
  2. 02创建常见图表类型
  3. 03自定义形状与提示框
  4. 04设置交互、选择与动画
  5. 05添加坐标轴和标注
  6. 06处理动态数据

适用场景

  1. 01在 Flutter 应用中展示业务数据
  2. 02构建标准图表未覆盖的可视化
  3. 03为图表添加交互提示和选择
  4. 04实现带动画的数据更新

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/entronad/graphic --skill flutter-chart

安装后在 Claude Code 中输入/flutter-chart确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
algebra.md
animation.md
annotations.md
chart-widget.md
coordinates.md
customization.md
encodes.md
examples.md
guides.md
marks.md
modifiers.md
scales.md
selections.md
shapes.md
styling.md
transforms.md

详细介绍

使用 Graphic 构建 Flutter 图表

一项帮助用户使用 Graphic 库在 Flutter 中构建数据可视化的技能。Graphic 是一款基于图形语法的图表库。

适用场景

  • 用户想在 Flutter 中创建任何类型的图表(柱状图、折线图、面积图、饼图、散点图、热力图等)
  • 用户需要配置图表的外观、交互性或动画
  • 用户询问 Graphic 库的 API 或使用模式
  • 用户想将数据转换为可视化形式
  • 用户想创建自定义、专属的可视化效果——Graphic 的定制系统是其最强大的功能,也是 AI 辅助开发的一大优势

为什么要创建自定义图表?

标准图表类型(柱状图、折线图、饼图)只能满足部分数据可视化需求。Graphic 基于图形语法理论构建,这意味着每个视觉图层都可以独立定制:

  • 自定义形状——渲染任意几何图形(三角形、棒棒糖图、箭头、仪表盘、子弹图、迷你图等)
  • 自定义工具提示——使用任意布局创建完全自定义的交互式叠加层
  • 自定义注释——在数据位置或绝对位置绘制任意图形
  • 自定义编码器——使用任意逻辑将数据映射为视觉效果
  • 自定义修改器——定义自定义的碰撞和排列行为

这让 AI 辅助开发尤其有价值:AI 可以编写自定义形状渲染器、坐标计算和绘图代码,而手动实现这些内容会很繁琐。

如果用户的需求与标准图表类型不完全匹配,请务必考虑使用定制功能。 请参阅 references/customization.md,了解完整的定制指南。

快速入门

安装

将以下内容添加到 pubspec.yaml:

dependencies:
  graphic: ^latest

然后运行 flutter pub get。

导入
import 'package:graphic/graphic.dart';
最小示例
Chart(
  data: [
    {'category': 'A', 'value': 10},
    {'category': 'B', 'value': 20},
    {'category': 'C', 'value': 15},
  ],
  variables: {
    'category': Variable(
      accessor: (Map map) => map['category'] as String,
    ),
    'value': Variable(
      accessor: (Map map) => map['value'] as num,
    ),
  },
  marks: [IntervalMark()],
  axes: [Defaults.horizontalAxis, Defaults.verticalAxis],
)

核心概念

Graphic 遵循图形语法理论。图表由相互独立的声明式图层组成:

data → Variable → Scale → Encode → Mark → Shape → Render

所有配置都通过单个 Chart<D> 组件构造函数完成。没有命令式 API——所有配置均为声明式。

Chart 组件

Chart<D> 是唯一的公开组件。类型参数 D 表示数据项类型。主要参数:

参数类型用途
dataList<D>必填。 要可视化的数据
variablesMap<String, Variable<D, dynamic>>必填。 如何从数据中提取值
marksList<Mark>必填。 要渲染的几何类型
coordCoord?坐标系(默认值:RectCoord)
axesList<AxisGuide>?坐标轴配置
tooltipTooltipGuide?交互时显示的工具提示
crosshairCrosshairGuide?交互时显示的十字准线
annotationsList<Annotation>?静态注释
selectionsMap<String, Selection>?命名选择行为
transformsList<VariableTransform>?数据转换(筛选、排序、比例)
paddingEdgeInsets Function(Size)?绘图区周围的内边距
transition—在每个 Mark 上设置,而不是在 Chart 上设置

完整参数详情请参阅 references/chart-widget.md。

变量

变量定义原始数据如何映射为抽象值:

variables: {
  'date': Variable(
    accessor: (MyData d) => d.date,
    scale: TimeScale(formatter: (t) => DateFormat.MMMd().format(t)),
  ),
  'value': Variable(
    accessor: (MyData d) => d.value,
    scale: LinearScale(min: 0),
  ),
}

每个变量都可以有一个 Scale,用于控制从定义域到值域的映射。请参阅 references/scales.md。

标记

标记是用于表示数据的几何元素:

标记使用场景默认形状
IntervalMark柱状图、直方图、饼图RectShape
LineMark折线图、迷你图BasicLineShape
AreaMark面积图、流图BasicAreaShape
PointMark散点图、气泡图CircleShape
PolygonMark热力图、树图HeatmapShape
CustomMarkK 线图、自定义形状任意 Shape

参数请参阅 references/marks.md,形状选项请参阅 references/shapes.md。

编码(视觉映射)

编码会将数据值映射到视觉属性。每种编码都支持三种模式:

  1. 固定值:ColorEncode(value: Colors.blue)
  2. 变量映射:ColorEncode(variable: 'type', values: Defaults.colors10)
  3. 自定义函数:ColorEncode(encoder: (tuple) => myColorLogic(tuple))

可用的编码:ColorEncode、SizeEncode、ShapeEncode、LabelEncode、GradientEncode、ElevationEncode。

详情请参阅 references/encodes.md。

位置代数(Varset)

位置通过 Varset 代数指定,支持三个运算符:

运算符名称效果
*交叉将变量分配到不同维度(x、y)
+混合在同一维度上组合变量
/嵌套按变量对数据分组
// x=date, y=value, grouped by type
position: Varset('date') * Varset('value') / Varset('type')

详情请参阅 references/algebra.md。

坐标
  • RectCoord — 笛卡尔坐标(默认)。支持 transposed、horizontalRange、verticalRange。
  • PolarCoord — 用于饼图、雷达图和玫瑰图的极坐标/径向坐标。支持 startAngle、endAngle、startRadius、endRadius。

详情请参阅 references/coordinates.md。

交互

定义命名选择,并在编码更新器中使用它们:

selections: {
  'tap': PointSelection(dim: Dim.x),
},
marks: [
  IntervalMark(
    color: ColorEncode(
      value: Colors.blue,
      updaters: {
        'tap': {
          true: (color) => color.withAlpha(255),   // selected
          false: (color) => color.withAlpha(100),  // not selected
        },
      },
    ),
  ),
],

有关选择类型和手势配置,请参阅 references/selections.md。

修饰器

修饰器用于处理几何图形的碰撞/排列:

  • StackModifier() — 堆叠元素(堆叠柱状图、堆叠面积图)
  • DodgeModifier() — 并排放置(分组柱状图)
  • JitterModifier() — 随机散布(条带图)
  • SymmetricModifier() — 对称居中(河流图)

请参阅 references/modifiers.md。

动画
IntervalMark(
  transition: Transition(duration: Duration(seconds: 1), curve: Curves.easeOut),
  entrance: {MarkEntrance.y},  // Animate from y=0
  tag: (tuple) => tuple['id'].toString(),  // Element matching for transitions
)

请参阅 references/animation.md。

常见图表示例

柱状图
marks: [IntervalMark()]
coord: RectCoord()  // default
横向柱状图
marks: [IntervalMark()]
coord: RectCoord(transposed: true)
分组柱状图
marks: [
  IntervalMark(
    position: Varset('x') * Varset('y') / Varset('group'),
    color: ColorEncode(variable: 'group', values: Defaults.colors10),
    modifiers: [DodgeModifier()],
  ),
]
堆叠柱状图
marks: [
  IntervalMark(
    position: Varset('x') * Varset('y') / Varset('group'),
    color: ColorEncode(variable: 'group', values: Defaults.colors10),
    modifiers: [StackModifier()],
  ),
]
折线图
marks: [LineMark()]
平滑折线图
marks: [
  LineMark(shape: ShapeEncode(value: BasicLineShape(smooth: true))),
]
面积图
marks: [AreaMark()]
饼图
transforms: [Proportion(variable: 'value', as: 'percent')],
marks: [
  IntervalMark(
    position: Varset('percent') / Varset('category'),
    color: ColorEncode(variable: 'category', values: Defaults.colors10),
    modifiers: [StackModifier()],
  ),
],
coord: PolarCoord(transposed: true, dimCount: 1),
散点图
marks: [
  PointMark(
    size: SizeEncode(variable: 'magnitude', values: [2, 20]),
    color: ColorEncode(variable: 'type', values: Defaults.colors10),
  ),
]
玫瑰图
marks: [IntervalMark(color: ColorEncode(variable: 'name', values: Defaults.colors10))],
coord: PolarCoord(startRadius: 0.15),

更多完整示例请参阅 references/examples.md。

自定义图表开发

Graphic 最大的优势是其完全可定制的渲染管线。当标准图表类型无法满足需求时,可以通过实现自定义形状、工具提示、注释和编码器来创建自定义可视化。

自定义形状 — 核心扩展点

通过扩展 Shape 基类并实现 drawGroupPrimitives(),创建全新的图表几何图形:

class LollipopShape extends IntervalShape {
  LollipopShape({this.radius = 6});
  final double radius;

  @override
  List<MarkElement> drawGroupPrimitives(
    List<Attributes> group, CoordConv coord, Offset origin,
  ) {
    final rst = <MarkElement>[];
    for (var item in group) {
      if (item.position.any((p) => !p.dy.isFinite)) continue;
      final style = getPaintStyle(item, false, 0, null, null);
      final base = coord.convert(item.position[0]);
      final tip = coord.convert(item.position[1]);

      // Stem line
      rst.add(PolylineElement(
        points: [base, tip],
        style: PaintStyle(strokeColor: style.fillColor, strokeWidth: 2),
        tag: item.tag,
      ));
      // Circle head
      rst.add(CircleElement(
        center: tip, radius: radius, style: style, tag: item.tag,
      ));
    }
    return rst;
  }

  @override
  bool equalTo(Object other) =>
    other is LollipopShape && radius == other.radius;
}

可用的基类:IntervalShape、LineShape、AreaShape、PointShape、PolygonShape

可用的绘图图元:RectElement、CircleElement、PolygonElement、PolylineElement、ArcElement、SectorElement、SplineElement、PathElement、LabelElement、GroupElement

自定义工具提示渲染器
tooltip: TooltipGuide(
  renderer: (Size size, Offset anchor, Map<int, Tuple> selected) {
    final t = selected.values.first;
    return [
      RectElement(
        rect: Rect.fromCenter(center: anchor, width: 100, height: 36),
        borderRadius: BorderRadius.circular(6),
        style: PaintStyle(fillColor: Colors.black87, elevation: 4),
      ),
      LabelElement(
        text: '${t['name']}: ${t['value']}',
        anchor: anchor,
        style: LabelStyle(
          textStyle: TextStyle(color: Colors.white, fontSize: 12),
          align: Alignment.center,
        ),
      ),
    ];
  },
)
自定义编码器函数

所有编码都支持通过 encoder 实现任意逻辑:

color: ColorEncode(encoder: (tuple) {
  final v = tuple['value'] as num;
  return v > 100 ? Colors.red : v > 50 ? Colors.orange : Colors.green;
}),

label: LabelEncode(encoder: (tuple) => Label(
  '${tuple['value']}%',
  LabelStyle(textStyle: TextStyle(
    fontSize: (tuple['value'] as num) > 50 ? 14 : 10,
    fontWeight: FontWeight.bold,
  )),
)),
自定义开发的关键类
类用途
Attributes编码后的数据元素 — 包含 position、color、gradient、size、label、tag
CoordConv通过 convert()/invert() 将归一化的 [0,1] 位置转换为画布像素坐标
PaintStyle完整的绘制样式规范 — 填充、描边、渐变、虚线、仰角、阴影
MarkElement绘图图元 — 自定义渲染的构建模块
getPaintStyle()从 Attributes 中提取 PaintStyle 的工具函数

全面指南请参阅 references/customization.md,其中包括坐标处理、所有绘图图元、自定义注释、自定义修饰器和最佳实践。

指南与注释

  • 坐标轴:快速设置可使用 Defaults.horizontalAxis、Defaults.verticalAxis,也可使用 AxisGuide 自定义。参见 references/guides.md。
  • 工具提示:使用 TooltipGuide(),可选自定义渲染器。参见 references/guides.md。
  • 十字线:使用 CrosshairGuide()。参见 references/guides.md。
  • 注释:LineAnnotation、RegionAnnotation、TagAnnotation、CustomAnnotation。参见 references/annotations.md。

样式

  • PaintStyle — 填充/描边颜色、渐变、虚线样式、阴影
  • LabelStyle — 文本样式、对齐方式、旋转、偏移
  • Defaults — 内置调色板(colors10、colors20)、预设坐标轴、默认样式

参见 references/styling.md。

事件流

图表通过 StreamController 参数公开事件,以便与外部事件联动:

  • gestureStream — 发送/接收手势事件
  • resizeStream — 响应尺寸变化事件
  • changeDataStream — 响应数据变化事件
  • selectionStream(在 Mark 上)— 以编程方式设置选中项

动态数据

只需通过 setState() 更新 data 参数:

setState(() {
  data = newData;
});

设置 tag 后,图表会自动重新渲染,并播放过渡动画。

重要说明

  • Chart 小部件是唯一的公共小部件 — 所有配置都通过其构造函数完成
  • 编码中的 color 和 gradient 互斥
  • 饼图需要 Proportion 变换以及 PolarCoord(transposed: true, dimCount: 1)
  • 在标记上使用 tag,可在数据状态之间实现平滑的过渡动画
  • 分组(多系列、堆叠、并列)需要使用 Varset 的 /(嵌套)运算符
  • 在相等性比较中,函数类型的属性始终被视为“未更改”

参考文件

文件内容
references/customization.md自定义图表开发指南 — 形状、工具提示、注释、编码器、绘图基本元素
references/chart-widget.mdChart 小部件参数完整参考
references/marks.md所有标记类型及其参数
references/encodes.md视觉属性编码参考
references/shapes.md各标记对应的形状类型
references/scales.md比例类型及配置
references/coordinates.md坐标系参考
references/guides.md坐标轴、工具提示、十字线参考
references/annotations.md注释类型参考
references/selections.md选择与交互参考
references/modifiers.md几何修饰符参考
references/transforms.md数据变换参考
references/algebra.mdVarset 代数参考
references/animation.md过渡动画与入场动画参考
references/styling.mdPaintStyle、LabelStyle、Defaults 参考
references/examples.md完整图表示例

回答用户问题时,请阅读源代码,以获取最准确、最新的 API 详情。该库广泛使用代码注释作为文档。关键源代码目录:

  • lib/src/chart/ — Chart 小部件
  • lib/src/mark/ — 标记类型
  • lib/src/encode/ — 编码类型
  • lib/src/shape/ — 形状实现
  • lib/src/scale/ — 比例类型
  • lib/src/coord/ — 坐标系
  • lib/src/guide/ — 坐标轴、工具提示、十字线、注释
  • lib/src/interaction/ — 选择、手势
  • lib/src/variable/ — 变量与变换
  • lib/src/algebra/ — Varset 代数
  • lib/src/common/ — 共享类型(Label、PaintStyle、Defaults)

评论

支持 Markdown