flutter - 加快“charts_flutter”线图渲染
问题描述
我目前正在开发一个颤振应用程序,它将实时绘制来自 BLE 设备的数据折线图(其中数据将以示波器样式格式显示)。作为实时 BLE 数据的占位符,我使用计时器回调来生成并绘制带有“charts_flutter”包的正弦波。到目前为止,一切似乎都在工作。但是,当更新周期小于 500 毫秒时,图表渲染似乎难以跟上(例如,将其设置为 200 毫秒会导致一切冻结)。在我开始尝试不同的包之前,我想看看是否有人有提示或建议来加快速度。我可能只是在状态管理等方面做错了,因为我对颤振没有那么丰富的经验。代码很短,所以我 已包含以下两个项目文件。谢谢。
主要.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”根本不适合实时数据。我最终通过扩展自定义画家编写了自己的示波器小部件,它没有明显的性能问题。
推荐阅读
- postgresql-9.5 - postgresql相同表的大小不同
- oauth - TYPO3 外部认证服务器
- excel - 如果下一列中有空白单元格,则连接两个单元格
- google-cloud-platform - GCP - gcloud 列出所有帐户及其有权访问的数据集
- html - CSS中纯文本的控制样式
- python-3.x - 为什么找不到我的文件,因此总是会重新创建?
- django - 使用多个请求调用 get_user 时,firebase-admin-python 很慢
- c# - MVC 在 Controller / Action 执行前暂停
- r - 从情节中删除连续图例
- python - arr = [1, 2, 3] 的引用 arr 存储在哪里?