Flutter自定义线条绘制插件flexi_kline的使用

Flutter自定义线条绘制插件FlexiKline的使用

FlexiKline 是一个灵活且高度可定制化的金融 K 线图表框架,旨在满足不同用户的需求。

Demo

你可以访问 FlexiKline Demo 查看效果。

特性

  • 自定义指标:实现指标配置与绘制对象接口。
  • 自定义绘制工具:实现绘制工具接口。
  • 支持全屏/横屏/主副区图表宽高设定与动态调整
  • 可定制化与持久化样式、配置、参数(包括指标/绘制等所有功能)
  • 适配多平台手势操作,且可定制化操作(惯性平移/缩放位置等)
  • 支持多种平台 (Android, iOS, Web, MacOs, Windows, Linux)

示例代码

1. 自定义 FlexiKlineConfiguration

实现 IConfiguration 接口。

/// FlexiKline配置接口
abstract interface class IConfiguration {
  /// 当前配置主题
  IFlexiKlineTheme get theme;

  /// 获取FlexiKline配置
  /// 1. 如果本地有缓存, 则从缓存中获取.
  /// 2. 如果本地没有缓存, 根据当前主题生成一套FlexiKline配置.
  FlexiKlineConfig getFlexiKlineConfig();

  /// 保存[config]配置信息到本地.
  void saveFlexiKlineConfig(FlexiKlineConfig config);

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

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

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

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

  /// 绘制工具定制
  Map<IDrawType, DrawObjectBuilder> drawObjectBuilders();

  /// 从本地获取[instId]对应的绘制实例数据列表.
  Iterable<Overlay> getDrawOverlayList(String instId);

  /// 以[instId]为key, 持久化绘制实例列表[list]到本地中.
  void saveDrawOverlayList(String instId, Iterable<Overlay> list);
}

主题配置参见 IFlexiKlineTheme

推荐混入 FlexiKlineThemeConfigurationMixin 实现。

2. 新建 FlexiKlineController

controller = FlexiKlineController(
  configuration: configuration,
  logger: LoggerImpl(
    tag: "FlexiKline",
    debug: kDebugMode,
  ),
);

3. 使用 FlexiKlineWidget

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

4. 更新K线数据

/// 根据[request]切换当前K线图表数据源[KlineData]; 如果发生变更TimerBar时.
flexiKlineController.switchKlineData(request, useCacheFirst: true);

/// 更新[request]指定的数据
flexiKlineController.updateKlineData(request, resp.data);

自定义指标

例如,实现一个移动平均指标线:

/// MA 移动平均指标线指标配置
class MAIndicator extends SinglePaintObjectIndicator {
  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](/user/override)
  SinglePaintObjectBox createPaintObject(IPaintContext context) {
    return MAPaintObject(context: context, indicator: this);
  }
}

/// MA指标绘制对象
class MAPaintObject<T extends MAIndicator> extends SinglePaintObjectBox<T> {

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

  [@override](/user/override)
  MinMax? initState(int start, int end) {
    // TODO: 返回[start ~ end)之间的数据范围, 即最大最小的MA指标值.
  }

  [@override](/user/override)
  void paintChart(Canvas canvas, Size size) {
    // TODO: 绘制MA移动平均指标线
    ...
    paintTips(canvas, model: klineData.latest);
  }

  [@override](/user/override)
  void onCross(Canvas canvas, Offset offset) {
    // TODO: 当十字线移动时回调
    ...
    paintTips(canvas, offset: offset);
  }

  [@override](/user/override)
  Size? paintTips(
    Canvas canvas, {
    CandleModel? model,
    Offset? offset,
    Rect? tipsRect, // Tips限定的绘制区域
  }) {
    // TODO: 绘制顶部MA Tips信息
  }
}

自定义绘制工具

例如,实现一个射线绘制工具:

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

  [@override](/user/override)
  bool hitTest(IDrawContext context, Offset position, {bool isMove = false}) {
    // TODO: 判断[position]是否命中当前射线
  }

  [@override](/user/override)
  void draw(IDrawContext context, Canvas canvas, Size size) {
    // TODO: 绘制射线
  }
}

更多关于Flutter自定义线条绘制插件flexi_kline的使用的实战教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter自定义线条绘制插件flexi_kline的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用flexi_kline插件进行自定义线条绘制的示例代码。flexi_kline是一个用于绘制K线图的Flutter插件,支持高度自定义,适用于金融数据的可视化。

首先,确保你已经在pubspec.yaml文件中添加了flexi_kline依赖:

dependencies:
  flutter:
    sdk: flutter
  flexi_kline: ^最新版本号  # 请替换为实际的最新版本号

然后,运行flutter pub get来安装依赖。

接下来是一个完整的示例代码,展示了如何使用flexi_kline插件绘制自定义的K线图:

import 'package:flutter/material.dart';
import 'package:flexi_kline/flexi_kline.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flexi Kline Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  // 示例数据
  List<KLineData> _kLineDataList = [];

  @override
  void initState() {
    super.initState();
    // 初始化示例数据
    _initKLineData();
  }

  void _initKLineData() {
    // 这里生成一些示例数据,实际应用中应该从API获取数据
    DateTime now = DateTime.now();
    for (int i = 0; i < 50; i++) {
      DateTime date = now.subtract(Duration(days: i));
      double open = 100 + (i % 10).toDouble();
      double high = open + ((i % 5) + 1).toDouble();
      double low = open - ((i % 5) + 1).toDouble();
      double close = (i % 2 == 0) ? high : low;
      _kLineDataList.add(KLineData(
        date: date,
        open: open,
        high: high,
        low: low,
        close: close,
        volume: 1000 + i,  // 成交量,可选字段
      ));
    }
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text('Flexi Kline Demo'),
      ),
      body: Center(
        child: Container(
          width: double.infinity,
          height: 400,
          child: FlexiKline(
            kLineDataList: _kLineDataList,
            // 自定义样式
            mainLineColor: Colors.blue,
            upLineColor: Colors.green,
            downLineColor: Colors.red,
            volumeColor: Colors.grey,
            gridColor: Colors.grey[300]!,
            gridLineWidth: 0.5,
            candleWidthRatio: 0.4,
            crosshairColor: Colors.blueAccent,
            crosshairLineWidth: 1.0,
            // 自定义交互
            onCrosshairMove: (crosshairPosition) {
              print('Crosshair moved to: $crosshairPosition');
            },
          ),
        ),
      ),
    );
  }
}

// KLineData类定义(假设flexi_kline插件没有自带这个类,实际使用时请参考插件文档)
class KLineData {
  DateTime date;
  double open;
  double high;
  double low;
  double close;
  int volume; // 可选字段,成交量

  KLineData({
    required this.date,
    required this.open,
    required this.high,
    required this.low,
    required this.close,
    this.volume = 0,
  });
}

请注意,上述代码中的KLineData类是一个假设的定义,因为具体的数据结构可能会根据flexi_kline插件的实际API有所不同。你应该参考flexi_kline的官方文档来获取正确的数据结构定义。

此外,FlexiKline组件的属性也可能需要根据实际插件版本进行调整。例如,一些属性名或默认值可能有所不同。务必查阅最新的flexi_kline文档以获取准确的信息。

这个示例展示了如何使用flexi_kline插件来绘制一个简单的K线图,并演示了如何自定义线条的颜色和样式。你可以根据需要进一步扩展和定制。

回到顶部