FlexiKline pub package

FlexiKline 是一个高度灵活且可定制的 Flutter 金融 K 线图表框架,适用于股票、数字货币等行情展示场景。

Demo

在线体验 | Android APK

版本要求

  • Flutter SDK: >= 3.27.0
  • Dart SDK: >= 3.6.0

特性

  • 自定义指标:实现指标配置与绘制对象接口,灵活扩展
  • 自定义绘制工具:实现绘制工具接口,支持多种绘图场景
  • 主副区布局:支持全屏 / 横屏,图表宽高可动态调整
  • 配置持久化:样式、参数、指标、绘制等所有功能均可定制与持久化
  • 手势操作:适配多平台,支持惯性平移、缩放位置、平移平滑等可定制操作
  • 多平台支持:Android、iOS、Web、macOS、Windows、Linux

安装

pubspec.yaml 中添加依赖:

dependencies:
  flexi_kline: ^2.0.0

然后运行:

flutter pub get

快速上手

1. 实现 IConfiguration 接口

自定义配置类,实现主题、指标构建器和绘制工具的定义。推荐混入 FlexiKlineThemeConfigurationMixin 获取默认配置。

abstract interface class IConfiguration implements IStorage {
  /// 当前配置主题
  IFlexiKlineTheme get theme;

  String get configKey;

  /// 生成FlexiKline配置
  FlexiKlineConfig generateFlexiKlineConfig([FlexiKlineConfig? origin]);

  /// 蜡烛指标配置构造器(主区)
  IndicatorBuilder<CandleBaseIndicator> get candleIndicatorBuilder;

  /// 时间指标配置构造器(副区)
  IndicatorBuilder<TimeBaseIndicator> get timeIndicatorBuilder;

  /// 主区指标配置定制
  Map<IIndicatorKey, IndicatorBuilder> get mainIndicatorBuilders;

  /// 副区指标配置定制
  Map<IIndicatorKey, IndicatorBuilder> get subIndicatorBuilders;

  /// 绘制工具定制
  Map<IDrawType, DrawObjectBuilder> get drawObjectBuilders;
}

2. 创建 FlexiKlineController

final configuration = FlexiKlineConfiguration();
controller = FlexiKlineController(
  configuration: configuration,
  logger: LoggerImpl(tag: "FlexiKline", debug: kDebugMode),
  subIndicatorMaxCount: defaultSubIndicatorMaxCount,
  klineDataCacheCapacity: 3,
);

3. 使用 FlexiKlineWidget

FlexiKlineWidget(
  controller: controller,
  mainBackgroundView: FlexiKlineMarkView(),
  mainForegroundViewBuilder: _buildKlineMainForgroundView,
  onDoubleTap: setFullScreen,
  drawToolbar: FlexiKlineDrawToolbar(controller: controller),
)

4. 更新数据

/// 切换数据源(如切换 TimeBar 时)
controller.switchKlineData(request);

/// 更新指定请求的数据
controller.updateKlineData(request, list);

自定义指标

v2.0.0 引入了类型化的指标体系,通过 IIndicatorKey sealed class 区分三类指标:

指标类型 Key 类型 Indicator 基类 PaintObject 基类 说明
普通指标 NormalIndicatorKey NormalIndicator NormalPaintObject 不占 slot,无需预计算;内置 Candle、Time 等均基于此,可自定义继承
数据指标 DataIndicatorKey DataIndicator DataPaintObject 需要 precompute,占 slot
业务指标 BusinessIndicatorKey BusinessIndicator BusinessPaintObject 由业务数据驱动,不占 slot

示例:自定义数据指标

/// 指标 Key
const maIndicatorKey = DataIndicatorKey('MA', label: 'MA');

/// 指标配置
class MAIndicator extends DataIndicator {
  MAIndicator({
    super.zIndex = 0,
    required super.height,
    super.padding = defaultMainIndicatorPadding,
    required this.calcParam,
    required this.tipsPadding,
    required this.lineWidth,
  }) : super(key: maIndicatorKey);

  final List<MaParam> calcParam;
  final EdgeInsets tipsPadding;
  final double lineWidth;

  @override
  DataPaintObject<MAIndicator> createPaintObject() => MAPaintObject();

  @override
  Map<String, dynamic> toJson() {
    return {"calcParam": calcParam.map((e) => e.toJson()).toList()};
  }
}

/// 指标绘制对象
class MAPaintObject extends DataPaintObject<MAIndicator> {

  @override
  bool shouldPrecompute(MAIndicator oldIndicator) {
    // 判断新旧指标配置的变化是否需要执行预计算
  }

  @override
  void precompute(Range range, {bool reset = false}) {
    // 针对 [range] 范围内的数据进行预计算(仅在数据更新时回调)
  }

  @override
  MinMax? initState(int start, int end) {
    // 返回 [start ~ end) 之间的指标最大最小值
  }

  @override
  void paintChart(Canvas canvas, Size size) {
    // 绘制指标线
  }

  @override
  void onCross(Canvas canvas, Offset offset) {
    // 十字线移动时回调
  }

  @override
  Size? paintTips(
    Canvas canvas, {
    CandleModel? model,
    Offset? offset,
    Rect? tipsRect,
  }) {
    // 绘制顶部 Tips 信息
  }
}

自定义绘制工具

class RayLineDrawObject extends DrawObject {
  RayLineDrawObject(super.overlay, super.config);

  @override
  bool hitTest(IDrawContext context, Offset position, {bool isMove = false}) {
    // 判断 [position] 是否命中当前绘制对象
  }

  @override
  void draw(IDrawContext context, Canvas canvas, Size size) {
    // 绘制图形
  }
}

配置

完整配置参考:FlexiKline 完整配置.json

License

Apache License 2.0

Libraries

flexi_kline