Flutter 股票 分時線、K線

尤先森發表於2020-07-21

借鑑自flutter_k_chart

公司專案中有涉及到股票類K線及分時線,原先使用flutter_k_chart,但是由於樣式及資料方面的問題,決定自己從頭開始畫一個。

移動端、WEB端都支援。 現有指標有MACDKDJBOLL

廢話不多說。先上圖

分時線
K線

點選K線圖,VOL視窗進行切換指標。

切換指標

MACD

KDJ

BOLL

HOW TO USE

demo 地址

github.com/GitHubYhb/H…

demo

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'package:HBLineChart/hb_kline_chart/hb_chart_data_util.dart';
import 'package:HBLineChart/hb_kline_chart/hb_k_line_chart.dart';
import 'package:HBLineChart/hb_kline_chart/hb_minute_line_chart.dart';

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'HBLineChart Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
        visualDensity: VisualDensity.adaptivePlatformDensity,
      ),
      home: TestPage(),
    );
  }
}

class TestPage extends StatefulWidget {
  @override
  _TestPageState createState() => _TestPageState();
}

class _TestPageState extends State<TestPage> {
  List datas = [];
  List klineDatas = [];

  @override
  void initState() {
    // getData();
    getMockMinuteData();
    getMockKlineData();
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(
        title: Text("元件測試"),
      ),
      body: ListView(
        children: <Widget>[
          HBMinuteLineChart(datas: datas),
          HBKLineChart(datas: klineDatas,)
        ],
      ),
    );
  }

  getMockMinuteData() {
    rootBundle
        .loadString('lib/hb_kline_chart/mock_data/minute_line.json')
        .then((result) {
      List dataList = jsonDecode(result);
      List newData = [];
      double maxPrice = 0, minPrice = double.infinity;
      double sumPirce = 0;
      double avePirce = 0;
      int maxv = 0;
      for (var i = 0; i < dataList.length; i++) {
        double prePrice =
            HBDataUtil.valueToNum(i == 0 ? "0" : dataList[i - 1]["price"])
                .toDouble();
        double price = HBDataUtil.valueToNum(dataList[i]["price"]).toDouble();
        int vol = HBDataUtil.valueToNum(dataList[i]["vol"]).toInt();
        // //漲跌狀態
        bool upDown = price > prePrice;
        sumPirce += price;
        avePirce = sumPirce / (i + 1);
        if (price > maxPrice) {
          maxPrice = price;
        }
        if (price < minPrice) {
          minPrice = price;
        }
        if (vol > maxv) {
          maxv = vol;
        }
        Map m = {
          "price": price,
          "vol": vol,
          "time": dataList[i]["time"],
          "upDown": upDown,
          "ave": avePirce
        };
        newData.add(m);
      }
      datas = newData;
      setState(() {});
    });
  }

  getMockKlineData() async {
    rootBundle
        .loadString('lib/hb_kline_chart/mock_data/k_line.json')
        .then((result) {
      List dataList = jsonDecode(result);
      List data = [];
      for (var i = 0; i < dataList.length; i++) {
        Map m = dataList[I];
        Map newMap = {
          "open": HBDataUtil.valueToNum(m["open"]).toDouble(),
          "high": HBDataUtil.valueToNum(m["high"]).toDouble(),
          "low": HBDataUtil.valueToNum(m["low"]).toDouble(),
          "close": HBDataUtil.valueToNum(m["close"]).toDouble(),
          "vol": HBDataUtil.valueToNum(m["vol"]).toDouble(),
          "date": m["date"],
        };
        data.add(newMap);
      }
      klineDatas = data;
      //計算各種指標
      HBDataUtil.calculate(klineDatas);
      setState(() {});
    });
  }
}

複製程式碼

資料

分時線

[
    {
        "price": 4542,
        "vol": 49722,
        "time": "20:00"
    },
    {
        "price": 4540,
        "vol": 26100,
        "time": "20:01"
    },
]
複製程式碼

重要提示:

分時線需要提前在/lib/hb_chart_config.dart中設定好整體長度lineChartCount,否則可能會出現顯示錯誤的問題。
image.png

K線

[
    {
        "open": "270.31",
        "high": "272.38",
        "low": "269.95",
        "close": "271.89",
        "vol": "66164",
        "date": "20170117"
    },
    {
        "open": "272.59",
        "high": "272.59",
        "low": "270.8",
        "close": "270.98",
        "vol": "71134",
        "date": "20170118"
    },
]
複製程式碼

UI

在檔案/lib/hb_chart_config.dart中,有各種顏色、寬度、長度等等。

import 'package:flutter/material.dart';

//分時線資料總長度
int lineChartCount = 781;
//柱狀圖最大寬度
double colMaxWidth = 5;

//蠟燭間隔
double candleSpace = 10;
//蠟燭寬度
double candleWidth = 8.5;
//蠟燭中間線的寬度
double candleLineWidth = 1.5;

//長按字型底色
Color timePriceTextColor = Colors.white;
//長按背景底色
Color timePriceMarkColor = Colors.blue;

//漲顏色
Color upColor = Colors.red;
//跌顏色
Color dnColor = Colors.green;

//交叉線寬度
double crossLineWidth = 0.5;
//交叉線顏色
Color crossLineColor = Colors.black;
//交叉線中心顏色
Color dotColor = Colors.red;

//分時線均線顏色
Color aveColor = Colors.purple;

//現價顏色
Color currentPriceColor = Colors.black87;
//均價顏色
Color avePriceColor = Colors.brown;

//各種指標線 三種顏色
Color kValue1Color = Colors.brown;
Color kValue2Color = Colors.blue;
Color kValue3Color = Colors.purple;

double leftFontSize = 12.0;
double topFontSize = 12.0;
double bottomFontSize = 10.0;

複製程式碼

相關文章