display dashed graph

This commit is contained in:
TAJAOUART Mounir 2023-02-09 11:25:48 +01:00
parent 12f41cad55
commit 6475847cb0
9 changed files with 212 additions and 95 deletions

2
android/local.properties Normal file
View File

@ -0,0 +1,2 @@
sdk.dir=/Users/aksel/Library/Android/sdk
flutter.sdk=/Users/aksel/development/flutter

View File

@ -1,4 +1,5 @@
import 'package:flutter/material.dart';
import 'package:real_time_chart/real_time_chart.dart';
void main() {
runApp(const MyApp());
@ -29,39 +30,44 @@ class MyHomePage extends StatefulWidget {
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() {
_counter++;
});
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.black,
appBar: AppBar(
title: Text(widget.title),
),
body: Center(
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
const Text(
'You have pushed the button this many times:',
),
Text(
'$_counter',
style: Theme.of(context).textTheme.headlineMedium,
),
],
child: Container(
color: Colors.red,
width: MediaQuery.of(context).size.width,
height: MediaQuery.of(context).size.width,
child: RealTimeGraph(
key: const Key('LiveGraph'),
stream: getDataStream(),
),
),
),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
);
}
int count = 0;
bool up = true;
Stream<double> getDataStream() {
return Stream.periodic(const Duration(milliseconds: 10), (_) {
if (count >= 100) {
up = false;
} else if (count <= 0) {
up = true;
}
if (up) {
count++;
} else {
count--;
}
return count * 1.0;
});
}
}

View File

@ -123,6 +123,13 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.8.2"
real_time_chart:
dependency: "direct main"
description:
path: ".."
relative: true
source: path
version: "0.0.1"
sky_engine:
dependency: transitive
description: flutter
@ -186,3 +193,4 @@ packages:
version: "2.1.4"
sdks:
dart: ">=2.19.2 <3.0.0"
flutter: ">=1.17.0"

View File

@ -1,90 +1,28 @@
name: example
description: A new Flutter project.
# The following line prevents the package from being accidentally published to
# pub.dev using `flutter pub publish`. This is preferred for private packages.
publish_to: 'none' # Remove this line if you wish to publish to pub.dev
publish_to: 'none'
# The following defines the version and build number for your application.
# A version number is three numbers separated by dots, like 1.2.43
# followed by an optional build number separated by a +.
# Both the version and the builder number may be overridden in flutter
# build by specifying --build-name and --build-number, respectively.
# In Android, build-name is used as versionName while build-number used as versionCode.
# Read more about Android versioning at https://developer.android.com/studio/publish/versioning
# In iOS, build-name is used as CFBundleShortVersionString while build-number is used as CFBundleVersion.
# Read more about iOS versioning at
# https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html
# In Windows, build-name is used as the major, minor, and patch parts
# of the product and file versions while build-number is used as the build suffix.
version: 1.0.0+1
environment:
sdk: '>=2.19.2 <3.0.0'
# Dependencies specify other packages that your package needs in order to work.
# To automatically upgrade your package dependencies to the latest versions
# consider running `flutter pub upgrade --major-versions`. Alternatively,
# dependencies can be manually updated by changing the version numbers below to
# the latest version available on pub.dev. To see which dependencies have newer
# versions available, run `flutter pub outdated`.
dependencies:
flutter:
sdk: flutter
# The following adds the Cupertino Icons font to your application.
# Use with the CupertinoIcons class for iOS style icons.
cupertino_icons: ^1.0.2
real_time_chart:
path: ../
dev_dependencies:
flutter_test:
sdk: flutter
# The "flutter_lints" package below contains a set of recommended lints to
# encourage good coding practices. The lint set provided by the package is
# activated in the `analysis_options.yaml` file located at the root of your
# package. See that file for information about deactivating specific lint
# rules and activating additional ones.
flutter_lints: ^2.0.0
# For information on the generic Dart part of this file, see the
# following page: https://dart.dev/tools/pub/pubspec
# The following section is specific to Flutter packages.
flutter:
# The following line ensures that the Material Icons font is
# included with your application, so that you can use the icons in
# the material Icons class.
uses-material-design: true
# To add assets to your application, add an assets section, like this:
# assets:
# - images/a_dot_burr.jpeg
# - images/a_dot_ham.jpeg
# An image asset can refer to one or more resolution-specific "variants", see
# https://flutter.dev/assets-and-images/#resolution-aware
# For details regarding adding assets from package dependencies, see
# https://flutter.dev/assets-and-images/#from-packages
# To add custom fonts to your application, add a fonts section here,
# in this "flutter" section. Each entry in this list should have a
# "family" key with the font family name, and a "fonts" key with a
# list giving the asset and other descriptors for the font. For
# example:
# fonts:
# - family: Schyler
# fonts:
# - asset: fonts/Schyler-Regular.ttf
# - asset: fonts/Schyler-Italic.ttf
# style: italic
# - family: Trajan Pro
# fonts:
# - asset: fonts/TrajanPro.ttf
# - asset: fonts/TrajanPro_Bold.ttf
# weight: 700
#
# For details regarding fonts from package dependencies,
# see https://flutter.dev/custom-fonts/#from-packages

View File

@ -0,0 +1,14 @@
// This is a generated file; do not edit or check into version control.
FLUTTER_ROOT=/Users/aksel/development/flutter
FLUTTER_APPLICATION_PATH=/Users/aksel/Documents/GitHub/real_time_chart
COCOAPODS_PARALLEL_CODE_SIGN=true
FLUTTER_TARGET=lib/main.dart
FLUTTER_BUILD_DIR=build
FLUTTER_BUILD_NAME=0.0.1
FLUTTER_BUILD_NUMBER=0.0.1
EXCLUDED_ARCHS[sdk=iphonesimulator*]=i386
EXCLUDED_ARCHS[sdk=iphoneos*]=armv7
DART_OBFUSCATION=false
TRACK_WIDGET_CREATION=true
TREE_SHAKE_ICONS=false
PACKAGE_CONFIG=.dart_tool/package_config.json

View File

@ -0,0 +1,13 @@
#!/bin/sh
# This is a generated file; do not edit or check into version control.
export "FLUTTER_ROOT=/Users/aksel/development/flutter"
export "FLUTTER_APPLICATION_PATH=/Users/aksel/Documents/GitHub/real_time_chart"
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
export "FLUTTER_TARGET=lib/main.dart"
export "FLUTTER_BUILD_DIR=build"
export "FLUTTER_BUILD_NAME=0.0.1"
export "FLUTTER_BUILD_NUMBER=0.0.1"
export "DART_OBFUSCATION=false"
export "TRACK_WIDGET_CREATION=true"
export "TREE_SHAKE_ICONS=false"
export "PACKAGE_CONFIG=.dart_tool/package_config.json"

View File

@ -1,7 +1,4 @@
library real_time_chart;
/// A Calculator.
class Calculator {
/// Returns [value] plus 1.
int addOne(int value) => value + 1;
}
export 'src/point.dart';
export 'src/live_chart.dart';

123
lib/src/live_chart.dart Normal file
View File

@ -0,0 +1,123 @@
import 'dart:async';
import 'dart:ui';
import 'package:flutter/material.dart';
import 'point.dart';
class RealTimeGraph extends StatefulWidget {
final Stream<double> stream;
const RealTimeGraph({Key? key, required this.stream}) : super(key: key);
@override
RealTimeGraphState createState() => RealTimeGraphState();
}
class RealTimeGraphState extends State<RealTimeGraph>
with TickerProviderStateMixin {
StreamSubscription<double>? streamSubscription;
List<Point<double>> _data = [];
Timer? timer;
@override
void initState() {
super.initState();
// Subscribe to the stream provided in the constructor
streamSubscription = widget.stream.listen(_listener);
// Start a periodic timer to update the data for visualization
timer = Timer.periodic(const Duration(milliseconds: 50), (_) {
//_data.removeWhere((element) => element.y > 100);
// Clone the data to avoid modifying the original list while iterating
List<Point<double>> data = _data.map((e) => e).toList();
// Increment the x value of each data point
for (var element in data) {
element.x = element.x - 1;
}
// Trigger a rebuild with the updated data
setState(() {
_data = data;
});
});
}
@override
Widget build(BuildContext context) {
return LayoutBuilder(
builder: (context, constraints) {
if (!constraints.maxWidth.isFinite || !constraints.maxHeight.isFinite) {
return const SizedBox.shrink();
}
return SizedBox(
key: Key('${constraints.maxWidth}${constraints.maxHeight}'),
height: constraints.maxWidth,
width: constraints.maxHeight,
child: CustomPaint(
painter: _GraphPainter(data: _data),
),
);
},
);
}
void _listener(double data) {
// Insert the new data point in the beginning of the list
_data.insert(0, Point(0, data));
}
@override
void dispose() {
// Clean up resources when the widget is removed from the tree
streamSubscription?.cancel();
timer?.cancel();
super.dispose();
}
}
class _GraphPainter extends CustomPainter {
final List<Point<double>> data;
_GraphPainter({required this.data});
@override
void paint(Canvas canvas, Size size) {
final paint = Paint()
..style = PaintingStyle.stroke
..strokeWidth = 1.5
..color = Colors.white;
List<Offset> points = [];
// Iterate over the data points and add intermediate points if necessary
for (int i = 0; i < data.length - 1; i++) {
double y1 = size.height - data[i].y;
double x1 = data[i].x + size.width;
double y2 = size.height - data[i + 1].y;
double x2 = data[i + 1].x + size.width;
double yDiff = y1 - y2;
double xDiff = x1 - x2;
// If the difference in y values is small, add intermediate points
if (xDiff.abs() <= 10) {
int numOfIntermediatePoints = (xDiff / 2).round();
double yInterval = yDiff / numOfIntermediatePoints;
double xInterval = xDiff / numOfIntermediatePoints;
for (int j = 1; j <= numOfIntermediatePoints; j++) {
double intermediateY = y1 + yInterval * j;
double intermediateX = x1 + xInterval * j;
points.add(Offset(intermediateX, intermediateY));
}
}
}
canvas.drawPoints(PointMode.points, points, paint);
}
@override
bool shouldRepaint(CustomPainter oldDelegate) => true;
}

16
lib/src/point.dart Normal file
View File

@ -0,0 +1,16 @@
class Point<T extends num> {
T x;
T y;
Point(this.x, this.y) {
this.x = x;
this.y = y;
}
@override
String toString() {
return 'Point{x: $x, y: $y}';
}
}