customize path between points and line display.
This commit is contained in:
parent
6c4c5a1c75
commit
0b2caaaf87
@ -39,17 +39,34 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||||||
appBar: AppBar(
|
appBar: AppBar(
|
||||||
title: Text(widget.title),
|
title: Text(widget.title),
|
||||||
),
|
),
|
||||||
body: Center(
|
body: Column(
|
||||||
|
children: [
|
||||||
|
Flexible(
|
||||||
child: Container(
|
child: Container(
|
||||||
color: Colors.red,
|
color: Colors.red,
|
||||||
width: MediaQuery.of(context).size.width,
|
width: MediaQuery.of(context).size.width,
|
||||||
height: MediaQuery.of(context).size.width,
|
height: MediaQuery.of(context).size.width,
|
||||||
child: RealTimeGraph(
|
child: RealTimeGraph(
|
||||||
key: const Key('LiveGraph'),
|
|
||||||
stream: getDataStream(),
|
stream: getDataStream(),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
const SizedBox(
|
||||||
|
height: 32,
|
||||||
|
),
|
||||||
|
Flexible(
|
||||||
|
child: Container(
|
||||||
|
color: Colors.red,
|
||||||
|
width: MediaQuery.of(context).size.width,
|
||||||
|
height: MediaQuery.of(context).size.width,
|
||||||
|
child: RealTimeGraph(
|
||||||
|
stream: getDataStream(),
|
||||||
|
displayMode: ChartDisplay.points,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,5 @@
|
|||||||
library real_time_chart;
|
library real_time_chart;
|
||||||
|
|
||||||
|
export 'src/chart_display.dart';
|
||||||
export 'src/point.dart';
|
export 'src/point.dart';
|
||||||
export 'src/live_chart.dart';
|
export 'src/live_chart.dart';
|
1
lib/src/chart_display.dart
Normal file
1
lib/src/chart_display.dart
Normal file
@ -0,0 +1 @@
|
|||||||
|
enum ChartDisplay { points, line }
|
@ -3,6 +3,7 @@ import 'dart:ui';
|
|||||||
|
|
||||||
import 'package:flutter/material.dart';
|
import 'package:flutter/material.dart';
|
||||||
|
|
||||||
|
import 'chart_display.dart';
|
||||||
import 'point.dart';
|
import 'point.dart';
|
||||||
|
|
||||||
class RealTimeGraph extends StatefulWidget {
|
class RealTimeGraph extends StatefulWidget {
|
||||||
@ -12,12 +13,14 @@ class RealTimeGraph extends StatefulWidget {
|
|||||||
this.speed = 1,
|
this.speed = 1,
|
||||||
required this.stream,
|
required this.stream,
|
||||||
this.pointsSpacing = 3.0,
|
this.pointsSpacing = 3.0,
|
||||||
|
this.displayMode = ChartDisplay.line,
|
||||||
}) : super(key: key);
|
}) : super(key: key);
|
||||||
|
|
||||||
final Stream<double> stream;
|
final Stream<double> stream;
|
||||||
final Duration updateDelay;
|
final Duration updateDelay;
|
||||||
final int speed;
|
final int speed;
|
||||||
final double pointsSpacing;
|
final double pointsSpacing;
|
||||||
|
final ChartDisplay displayMode;
|
||||||
|
|
||||||
@override
|
@override
|
||||||
RealTimeGraphState createState() => RealTimeGraphState();
|
RealTimeGraphState createState() => RealTimeGraphState();
|
||||||
@ -69,9 +72,13 @@ class RealTimeGraphState extends State<RealTimeGraph>
|
|||||||
height: constraints.maxWidth,
|
height: constraints.maxWidth,
|
||||||
width: constraints.maxHeight,
|
width: constraints.maxHeight,
|
||||||
child: CustomPaint(
|
child: CustomPaint(
|
||||||
painter: _PointsGraphPainter(
|
painter: widget.displayMode == ChartDisplay.points
|
||||||
|
? _PointsGraphPainter(
|
||||||
data: _data,
|
data: _data,
|
||||||
pointsSpacing: widget.pointsSpacing,
|
pointsSpacing: widget.pointsSpacing,
|
||||||
|
)
|
||||||
|
: _LineGraphPainter(
|
||||||
|
data: _data,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
@ -117,7 +124,6 @@ class _PointsGraphPainter extends CustomPainter {
|
|||||||
final y2 = size.height - data[i + 1].y;
|
final y2 = size.height - data[i + 1].y;
|
||||||
final x2 = data[i + 1].x + size.width;
|
final x2 = data[i + 1].x + size.width;
|
||||||
final yDiff = (y2 - y1).abs();
|
final yDiff = (y2 - y1).abs();
|
||||||
final xDiff = (x2 - x1).abs();
|
|
||||||
|
|
||||||
// If the difference in y values is small, add intermediate points
|
// If the difference in y values is small, add intermediate points
|
||||||
if (yDiff >= pointsSpacing) {
|
if (yDiff >= pointsSpacing) {
|
||||||
@ -128,7 +134,10 @@ class _PointsGraphPainter extends CustomPainter {
|
|||||||
final intermediateY = y1 + yInterval * j;
|
final intermediateY = y1 + yInterval * j;
|
||||||
final intermediateX = x1 + xInterval * j;
|
final intermediateX = x1 + xInterval * j;
|
||||||
canvas.drawPoints(
|
canvas.drawPoints(
|
||||||
PointMode.points, [Offset(intermediateX, intermediateY)], paint);
|
PointMode.points,
|
||||||
|
[Offset(intermediateX, intermediateY)],
|
||||||
|
paint,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,3 +146,32 @@ class _PointsGraphPainter extends CustomPainter {
|
|||||||
@override
|
@override
|
||||||
bool shouldRepaint(CustomPainter oldDelegate) => true;
|
bool shouldRepaint(CustomPainter oldDelegate) => true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class _LineGraphPainter extends CustomPainter {
|
||||||
|
final List<Point<double>> data;
|
||||||
|
|
||||||
|
_LineGraphPainter({required this.data});
|
||||||
|
|
||||||
|
@override
|
||||||
|
void paint(Canvas canvas, Size size) {
|
||||||
|
final paint = Paint()
|
||||||
|
..style = PaintingStyle.stroke
|
||||||
|
..strokeWidth = 1.5
|
||||||
|
..color = Colors.white;
|
||||||
|
Path path = Path();
|
||||||
|
|
||||||
|
// Iterate over the data points and add intermediate points if necessary
|
||||||
|
if (data.isNotEmpty) {
|
||||||
|
path.moveTo(data.first.x + size.width, size.height - data.first.y);
|
||||||
|
}
|
||||||
|
for (int i = 0; i < data.length - 1; i++) {
|
||||||
|
double y = size.height - data[i].y;
|
||||||
|
double x = data[i].x + size.width;
|
||||||
|
path.lineTo(x, y);
|
||||||
|
}
|
||||||
|
canvas.drawPath(path, paint);
|
||||||
|
}
|
||||||
|
|
||||||
|
@override
|
||||||
|
bool shouldRepaint(CustomPainter oldDelegate) => true;
|
||||||
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user