加速“charts_flutter”线图渲染

问题描述

我目前正在开发一个 Flutter 应用程序,该应用程序将在折线图上实时绘制来自 BLE 设备的数据(其中数据将以示波器样式格式显示)。作为实时 BLE 数据的占位符,我使用计时器回调来生成和绘制带有“charts_Flutter”包的正弦波。到目前为止,一切似乎都在起作用。但是,当更新周期小于 500 毫秒时,图表渲染似乎很难跟上(例如,将其设置为 200 毫秒会导致一切冻结)。在我开始尝试不同的软件包之前,我想看看是否有人有提示或建议来尝试加快速度。我可能只是在状态管理等方面做错了。因为我对颤振没有经验。代码很短,所以我在下面包含了两个项目文件。谢谢。

main.dart

import 'package:Flutter/material.dart';
import 'package:charts_Flutter/Flutter.dart';
import 'package:provider/provider.dart';

import 'package:tuple/tuple.dart';
import 'models/graph_data_model.dart';

void main() => runApp(new GraphDataApp());

class GraphDataApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MultiProvider(
      providers: [
        ChangeNotifierProvider<GraphDataModel>(
            create: (context) => GraphDataModel()),],child: MaterialApp(
        title: 'Data Plotter',theme: ThemeData(
          primarySwatch: Colors.blue,),initialRoute: '/',routes: {
          '/': (context) => MyApp(),},);
  }
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: Text("Data Plotter")),body: Center(
        child: Column(
          mainAxisAlignment: MainAxisAlignment.center,children: <Widget>[
            GraphDataWidget(),);
  }
}

class GraphDataWidget extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return Padding(
      padding: EdgeInsets.all(5.0),child: SizedBox(
        height: 400.0,child: Selector<GraphDataModel,Tuple2<GraphDataModel,double>>(
          selector: (_,graphDataModel) {
            return Tuple2(graphDataModel,graphDataModel.elapsedtime);
          },builder: (context,selectorTuple,child) {
            GraphDataModel graphDataModel = selectorTuple.item1;
            return LineChart(
                graphDataModel.series.toList(),animate: false,domainAxis: NumericAxisspec(
                    viewport: NumericExtents(graphDataModel.domainStart,graphDataModel.domainEnd))
            );
          },);
  }
}

graph_data_model.dart

import 'dart:async';
import 'dart:math';
import 'package:charts_Flutter/Flutter.dart';
import 'package:Flutter/material.dart';

const UPDATE_INTERVAL = 500;
const MAX_TIME_INTERVAL = 10.0;
const MAX_DATA_POINTS = ((MAX_TIME_INTERVAL * 1000) / UPDATE_INTERVAL);

class GraphDataModel extends ChangeNotifier {
  bool _running = false;
  int _startTime;
  double elapsedtime;
  List<Series<PlotPoint,double>> series;

  GraphDataModel() {
    // initialize the data series
    series = [
      Series<PlotPoint,double>(
        id: 'Sine',colorFn: (_,__) => MaterialPalette.blue.shadeDefault,domainFn: (PlotPoint point,_) => point.time,measureFn: (PlotPoint point,_) => point.value,data: <PlotPoint>[PlotPoint(0,0)],];

    // initialize the start time and start the timer
    _startTime = DateTime.Now().millisecondsSinceEpoch;
    Timer.periodic(Duration(milliseconds: UPDATE_INTERVAL),_timerCallback);
  }

  // getters
  num get domainStart => _running ? (series.first.data.first.time) : 0;
  num get domainEnd => _running ? (series.first.data.last.time) : 1;

  void _timerCallback(Timer t) {
    final currentTime = DateTime.Now().millisecondsSinceEpoch;
    // find the elapsed time in seconds
    elapsedtime = (currentTime - _startTime).todouble() / 1000.0;
    // find the sine value based on the elapsed time
    final yVal = sin((2.0 * pi * elapsedtime) / 10.0);

    // add the latest data point to the series
    series.first.data.add(PlotPoint(elapsedtime,yVal));
    // remove the first element in the list to create oscilloscope scrolling effect
    if(series.first.data.length > MAX_DATA_POINTS.toInt() || !_running) {
      series.first.data.removeAt(0);
    }
    _running = true;
    notifyListeners();
  }
}

class PlotPoint {
  final double time;
  final double value;

  PlotPoint(this.time,this.value);
}

解决方法

我得出的结论是,“charts_flutter”根本不适合实时数据。我最终通过扩展自定义画家编写了自己的示波器小部件,并且没有明显的性能问题。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...