import 'dart:async'; import 'dart:core'; import 'dart:math' as math; import 'package:fl_chart/fl_chart.dart'; import 'package:flutter/material.dart'; import 'package:logging/logging.dart'; class Plot extends StatefulWidget { const Plot({ super.key, required this.title, required this.aspectRatio, required this.maxTimeSeconds, required this.readAnalog, required this.sampleTimeMillis}); final String title; final double aspectRatio; final int maxTimeSeconds; final Future Function() readAnalog; final int sampleTimeMillis; @override State createState() => _Plot(); } class _Plot extends State { late Timer timer; late int limit= ((widget.maxTimeSeconds)/(widget.sampleTimeMillis/1000)).toInt(); late List adc = []; int index = 0; double el = 0.0; late Logger log; @override void dispose() { super.dispose(); timer.cancel(); } @override void initState() { super.initState(); log = Logger("Plot : ${widget.title}"); log.info('limit : $limit'); timer = Timer.periodic(Duration(milliseconds: widget.sampleTimeMillis), (timer) { widget.readAnalog().then((val){ if (index>=limit) { log.info('================================================================ reset $index : $el : ${index != 0 ? adc[index-1] : 0}'); index = 0; el = 0.0; adc.clear(); } setState(() { el = (index * widget.sampleTimeMillis)/1000; adc.add(FlSpot( el, val)); log.info('================================================================ $index : $el : ${adc[index]}'); index +=1; }); }); }); } @override Widget build(BuildContext context) { return AspectRatio( aspectRatio: widget.aspectRatio, child : LineChart( LineChartData( minY: -5, maxY: 5, minX: 0, maxX: widget.maxTimeSeconds.toDouble(), lineBarsData: [LineChartBarData( spots: adc, dotData: const FlDotData( show: false, ), barWidth: 2, isCurved: false, )], titlesData: const FlTitlesData(show: true, rightTitles: AxisTitles(sideTitles: SideTitles(reservedSize: 40, showTitles: false)), topTitles: AxisTitles(sideTitles: SideTitles(reservedSize: 40, showTitles: false)), ), gridData: const FlGridData(show: true, drawVerticalLine: false), ) ) ); } } class DummyData { late int limitCount; late List sinPoints; double xValue = 0; double step = 0.05; int index = 0; late Timer timer; late void Function() stateChange; DummyData(){ limitCount = (20/step).toInt(); sinPoints = List.generate(limitCount+1, (index) => FlSpot(index+step,0)); } void begin(Function() sc) { stateChange = sc; timer = Timer.periodic(const Duration(milliseconds: 2), (timer) { stateChange.call(); if (xValue >= 20) { xValue = 0; index = 0; sinPoints.clear(); } else { xValue += step; index += 1; } // print("$index : $xValue"); }); } void update(){ sinPoints.insert(index, FlSpot(xValue, 1 - (math.Random(xValue.toInt()).nextDouble()*2))); } }