flutter自定义系列之简单的K线图绘制

这篇具有很好参考价值的文章主要介绍了flutter自定义系列之简单的K线图绘制。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

上篇文章讲了flutter自定义的相关流程,

今天继续练习下flutter的自定义K线:

我们可以通过自定义Painter来实现一个简单的K线图界面:

  1. 创建一个自定义的Painter,用于绘制K线图:
import 'dart:ui';

import 'package:flutter/material.dart';

class KLinePainter extends CustomPainter {
  final List<dynamic> data;
  final double itemWidth;
  final double scaleFactor;

  KLinePainter({required this.data, required this.itemWidth, required this.scaleFactor});

  @override
  void paint(Canvas canvas, Size size) {
    // 设置画笔
    final linePaint = Paint()
      ..color = Colors.grey
      ..strokeWidth = 0.5;

    final textPainter = TextPainter(textDirection: TextDirection.ltr, textAlign: TextAlign.left);

    // 计算价格范围和最大成交量
    num highestPrice = double.minPositive;
    num lowestPrice = double.maxFinite;
    num highestVolume = double.minPositive;

    for (var item in data) {
      if (item['high'] > highestPrice) {
        highestPrice = item['high'];
      }
      if (item['low'] < lowestPrice) {
        lowestPrice = item['low'];
      }
      if (item['vol'] > highestVolume) {
        highestVolume = item['vol'];
      }
    }

    // 计算价格和成交量的缩放比例
    double priceScale = (size.height - 20) / (highestPrice - lowestPrice);
    double volumeScale = size.height * 0.2 / highestVolume;

    // 绘制K线图
    for (int i = 0; i < data.length; i++) {
      var item = data[i];

      double open = (item['open'] - lowestPrice) * priceScale;
      double close = (item['close'] - lowestPrice) * priceScale;
      double high = (item['high'] - lowestPrice) * priceScale;
      double low = (item['low'] - lowestPrice) * priceScale;
      double vol = item['vol'] * volumeScale;

      // 设置画笔颜色
      linePaint.color = close >= open ? Colors.green : Colors.red;

      // 绘制实体
      double halfWidth = itemWidth * scaleFactor / 2;
      double centerX = i * itemWidth * scaleFactor + halfWidth;
      canvas.drawRect(
        Rect.fromCenter(
          center: Offset(centerX, size.height - (open + close) / 2 - 10),
          width: itemWidth * scaleFactor,
          height: (open - close).abs(),
        ),
        linePaint,
      );

      // 绘制上下影线
      canvas.drawLine(Offset(centerX, size.height - high - 10), Offset(centerX, size.height - low - 10), linePaint);
    }
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}
  1. 创建一个StatefulWidget,用于处理缩放和滚动:
class KLineChart extends StatefulWidget {
  final List<dynamic> data;

  KLineChart({required this.data});

  @override
  _KLineChartState createState() => _KLineChartState();
}

class _KLineChartState extends State<KLineChart> {
  double _scaleFactor = 1.0;
  double _itemWidth = 10.0;
  late double _baseScaleFactor;

  @override
  void initState() {
    super.initState();
    _baseScaleFactor = _scaleFactor;
  }

  @override
  Widget build(BuildContext context) {
    return GestureDetector(
      onScaleStart: (details) {
        _baseScaleFactor = _scaleFactor;
      },
      onScaleUpdate: (details) {
        setState(() {
          // 修改这里,减小缩放速度
          _scaleFactor = _baseScaleFactor * (1.0 + (details.scale - 1.0) / 2);
        });
      },
      child: SingleChildScrollView(
        scrollDirection: Axis.horizontal,
        child: CustomPaint(
          size: Size(widget.data.length * _itemWidth * _scaleFactor, MediaQuery.of(context).size.height),
          painter: KLinePainter(data: widget.data, itemWidth: _itemWidth, scaleFactor: _scaleFactor),
        ),
      ),
    );
  }
}
  1. 在需要使用K线图的地方,调用KLineChart组件并传入K线数据:
List<dynamic> kLineData = [
  // 你的K线数据
];

KLineChart(data: kLineData);

这样,你就可以实现一个简单的可左右滑动、放大缩小的K线界面。

这里我们看看实现的效果:
我先模拟了一些K线数据:

List<dynamic> generateKLineData(int count) {
  List<dynamic> data = [];
  Random random = Random();
  double open = 100.0;
  double close, high, low;
  num volume;

  for (int i = 0; i < count; i++) {
    close = open + random.nextDouble() * 20 - 10;
    high = max(open, close) + random.nextDouble() * 5;
    low = min(open, close) - random.nextDouble() * 5;
    volume = random.nextInt(10000) + 1000;

    data.add({
      'open': open,
      'close': close,
      'high': high,
      'low': low,
      'vol': volume,
    });

    open = close;
  }

  return data;
}

之后直接引用:

SliverToBoxAdapter(
  child: SizedBox(
    height: 300.w,
    child: KLineChart(data: generateKLineData(100)),
  ),
)

运行后如下效果:

flutter自定义系列之简单的K线图绘制

可左右滑动,可伸缩,仅包含基本功能,真正的需要分时图,各种的指标,甚至是自定义的指标绘制等等,你可以根据需求进一步完善和优化。

技术人日拱一卒,共勉!文章来源地址https://www.toymoban.com/news/detail-479989.html

到了这里,关于flutter自定义系列之简单的K线图绘制的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Flutter系列文章-Flutter基础

    Flutter是Google推出的一种新的移动应用开发框架,允许开发者使用一套代码库同时开发Android和iOS应用。它的设计理念、框架结构、以及对Widget的使用,都让开发者能更有效率地创建高质量的应用。 Flutter的设计理念是“一切皆为Widget”。这意味着不论是按钮、字体、颜色、布局

    2024年02月16日
    浏览(34)
  • Flutter系列文章-Flutter应用优化

    当涉及到优化 Flutter 应用时,考虑性能、UI 渲染和内存管理是至关重要的。在本篇文章中,我们将通过实例深入讨论这些主题,展示如何通过优化技巧改进你的 Flutter 应用。 1. 使用 const 构造函数 在构建小部件时,尽可能使用 const 构造函数来创建静态小部件。这将避免在每次

    2024年02月11日
    浏览(34)
  • Flutter系列文章-Flutter 插件开发

    在本篇文章中,我们将学习如何开发 Flutter 插件,实现 Flutter 与原生平台的交互。我们将详细介绍插件的开发过程,包括如何创建插件项目、实现方法通信、处理异步任务等。最后,我们还将演示如何将插件打包并发布到 Flutter 社区。 在 Flutter 项目中,你可能需要与原生平台

    2024年02月11日
    浏览(27)
  • Flutter系列文章-Flutter进阶2

    这一节我将再详细地为您介绍 Flutter 进阶主题,包括导航和路由、状态管理、异步处理、HTTP请求和Rest API,以及数据持久化。让我们逐个介绍这些主题。 在 Flutter 中,导航和路由是构建多页面应用的关键概念。导航是指从一个页面(或称为路由)切换到另一个页面的过程。每

    2024年02月15日
    浏览(32)
  • Flutter系列文章-Flutter UI进阶

    在本篇文章中,我们将深入学习 Flutter UI 的进阶技巧,涵盖了布局原理、动画实现、自定义绘图和效果、以及 Material 和 Cupertino 组件库的使用。通过实例演示,你将更加了解如何创建复杂、令人印象深刻的用户界面。 Row 和 Column 是常用的布局组件,但灵活地使用它们可以带来

    2024年02月13日
    浏览(25)
  • Flutter系列文章-实战项目

    在本篇文章中,我们将通过一个实际的 Flutter 应用来综合运用最近学到的知识,包括保存到数据库、进行 HTTP 请求等。我们将开发一个简单的天气应用,可以根据用户输入的城市名获取该城市的天气信息,并将用户查询的城市列表保存到本地数据库中。 1. 确定项目目标 我们

    2024年02月13日
    浏览(28)
  • Flutter系列文章-Flutter环境搭建和Dart基础

    Flutter是Google推出的一个开源的、高性能的移动应用开发框架,可以用一套代码库开发Android和iOS应用。Dart则是Flutter所使用的编程语言。让我们来看看如何搭建Flutter开发环境,并了解Dart语言的基础知识。 1. 安装Flutter SDK 首先,访问Flutter官网下载Flutter SDK。选择适合你操作系统

    2024年02月15日
    浏览(35)
  • Flutter系列文章-Flutter在实际业务中的应用

    1. 跨平台开发: 在移动应用开发中,面对不同的平台(iOS和Android),我们通常需要编写两套不同的代码。而Flutter通过一套代码可以构建适用于多个平台的应用,大大提高了开发效率,降低了维护成本。 2. 混合开发: 在一些已有的原生应用中,引入Flutter可以用于开发某些特

    2024年02月11日
    浏览(30)
  • flutter的自定义系列雷达图

    自定义是flutter进阶中不可缺少的ui层知识点,这里我们来总结下: 在Flutter中,自定义绘制通常是通过使用 CustomPaint 和 CustomPainter 来实现的。 创建 CustomPaint 组件 首先,需要创建一个 CustomPaint 组件。 CustomPaint 是一个Widget,它可以作为其他组件的子组件,用于提供自定义绘制

    2024年02月09日
    浏览(35)
  • flutter系列之:如何自定义动画路由

    目录 简介 自定义跳转使用 flutter动画基础 实现一个自定义的route 总结 flutter中有默认的Route组件,叫做MaterialPageRoute,一般情况下我们在flutter中进行跳转的话,只需要向Navigator中传入一个MaterialPageRoute就可以了。 但是MaterialPageRoute太普通了,如果我们想要做点不同的跳转特效

    2023年04月19日
    浏览(34)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包