display dashed graph
This commit is contained in:
parent
12f41cad55
commit
6475847cb0
2
android/local.properties
Normal file
2
android/local.properties
Normal file
@ -0,0 +1,2 @@
|
||||
sdk.dir=/Users/aksel/Library/Android/sdk
|
||||
flutter.sdk=/Users/aksel/development/flutter
|
@ -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;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -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"
|
||||
|
@ -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
|
||||
|
14
ios/Flutter/Generated.xcconfig
Normal file
14
ios/Flutter/Generated.xcconfig
Normal 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
|
13
ios/Flutter/flutter_export_environment.sh
Executable file
13
ios/Flutter/flutter_export_environment.sh
Executable 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"
|
@ -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
123
lib/src/live_chart.dart
Normal 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
16
lib/src/point.dart
Normal 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}';
|
||||
}
|
||||
|
||||
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user