customize graphStroke

This commit is contained in:
TAJAOUART Mounir 2023-02-09 22:10:08 +01:00
parent 0cdb3db45f
commit 993603a02b
2 changed files with 90 additions and 51 deletions

View File

@ -46,20 +46,17 @@ class _MyHomePageState extends State<MyHomePage> {
child: Column( child: Column(
children: [ children: [
Expanded( Expanded(
child: Container( child: Padding(
color: Colors.green, padding: const EdgeInsets.all(16.0),
child: RealTimeGraph( child: RealTimeGraph(
stream: stream, stream: stream,
), ),
), ),
), ),
const SizedBox( const SizedBox(height: 32),
height: 32,
child: Divider(color: Colors.grey,),
),
Expanded( Expanded(
child: Container( child: Padding(
color: Colors.green, padding: const EdgeInsets.all(16.0),
child: RealTimeGraph( child: RealTimeGraph(
stream: stream, stream: stream,
displayMode: ChartDisplay.points, displayMode: ChartDisplay.points,

View File

@ -9,8 +9,9 @@ import 'point.dart';
class RealTimeGraph extends StatefulWidget { class RealTimeGraph extends StatefulWidget {
const RealTimeGraph({ const RealTimeGraph({
Key? key, Key? key,
this.updateDelay = const Duration(milliseconds: 100), this.updateDelay = const Duration(milliseconds: 50),
this.speed = 1, this.speed = 1,
this.graphStroke = 0.5,
required this.stream, required this.stream,
this.pointsSpacing = 3.0, this.pointsSpacing = 3.0,
this.displayMode = ChartDisplay.line, this.displayMode = ChartDisplay.line,
@ -19,6 +20,7 @@ class RealTimeGraph extends StatefulWidget {
final Stream<double> stream; final Stream<double> stream;
final Duration updateDelay; final Duration updateDelay;
final int speed; final int speed;
final double graphStroke;
final double pointsSpacing; final double pointsSpacing;
final ChartDisplay displayMode; final ChartDisplay displayMode;
@ -61,28 +63,59 @@ class RealTimeGraphState extends State<RealTimeGraph>
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return LayoutBuilder( return ClipRRect(
child: RepaintBoundary(
child: LayoutBuilder(
builder: (context, constraints) { builder: (context, constraints) {
if (!constraints.maxWidth.isFinite || !constraints.maxHeight.isFinite) { if (!constraints.maxWidth.isFinite ||
!constraints.maxHeight.isFinite) {
return const SizedBox.shrink(); return const SizedBox.shrink();
} }
return SizedBox( return SizedBox(
key: Key('${constraints.maxWidth}${constraints.maxHeight}'), key: Key('${constraints.maxWidth}${constraints.maxHeight}'),
height: constraints.maxWidth, height: constraints.maxHeight,
width: constraints.maxHeight, width: constraints.maxWidth,
child: CustomPaint( child: Row(
mainAxisSize: MainAxisSize.max,
children: [
Container(
color: Colors.grey,
width: 1,
height: constraints.maxHeight,
),
Column(
mainAxisSize: MainAxisSize.max,
children: [
CustomPaint(
size: Size(
constraints.maxWidth - 1,
constraints.maxHeight - 1,
),
painter: widget.displayMode == ChartDisplay.points painter: widget.displayMode == ChartDisplay.points
? _PointGraphPainter( ? _PointGraphPainter(
data: _data, data: _data,
pointSpacing: 3, pointsSpacing: widget.pointsSpacing,
graphStroke: widget.graphStroke,
) )
: _LineGraphPainter( : _LineGraphPainter(
data: _data, data: _data,
graphStroke: widget.graphStroke,
), ),
), ),
Container(
color: Colors.grey,
height: 1,
width: constraints.maxWidth - 1,
)
],
),
],
),
); );
}, },
),
),
); );
} }
@ -101,16 +134,21 @@ class RealTimeGraphState extends State<RealTimeGraph>
} }
class _PointGraphPainter extends CustomPainter { class _PointGraphPainter extends CustomPainter {
final List<Point<double>> data; _PointGraphPainter({
final double pointSpacing; required this.data,
required this.pointsSpacing,
required this.graphStroke,
});
_PointGraphPainter({required this.data, required this.pointSpacing}); final List<Point<double>> data;
final double pointsSpacing;
final double graphStroke;
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
final paint = Paint() final paint = Paint()
..style = PaintingStyle.fill ..style = PaintingStyle.fill
..strokeWidth = 1.5 ..strokeWidth = graphStroke
..color = Colors.white; ..color = Colors.white;
// Find the maximum y value in the data // Find the maximum y value in the data
@ -131,33 +169,33 @@ class _PointGraphPainter extends CustomPainter {
double y2 = data[i + 1].y * yScale; double y2 = data[i + 1].y * yScale;
double x2 = data[i + 1].x + size.width; double x2 = data[i + 1].x + size.width;
double yDiff = (y2 - y1).abs(); double yDiff = (y2 - y1).abs();
double 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 >= pointSpacing) { if (yDiff >= pointsSpacing || xDiff >= pointsSpacing) {
int numOfIntermediatePoints = (yDiff / pointSpacing).round(); int numOfIntermediatePoints = yDiff >= pointsSpacing
? (yDiff / pointsSpacing).round()
: (xDiff / pointsSpacing).round();
double yInterval = (y2 - y1) / numOfIntermediatePoints; double yInterval = (y2 - y1) / numOfIntermediatePoints;
double xInterval = (x2 - x1) / numOfIntermediatePoints; double xInterval = (x2 - x1) / numOfIntermediatePoints;
for (int j = 0; j <= numOfIntermediatePoints; j++) { for (int j = 0; j <= numOfIntermediatePoints; j++) {
double intermediateY = y1 + yInterval * j; final intermediateY = y1 + yInterval * j;
double intermediateX = x1 + xInterval * j; final intermediateX = x1 + xInterval * j;
if (intermediateX.isFinite && intermediateY.isFinite) {
canvas.drawCircle( canvas.drawCircle(
Offset(intermediateX, size.height - intermediateY), Offset(intermediateX, size.height - intermediateY),
1, sqrt(graphStroke),
paint, paint,
); );
} }
} }
}
canvas.drawCircle( canvas.drawCircle(
Offset(x1, size.height - y1), Offset(x1, size.height - y1),
1, sqrt(graphStroke),
paint, paint,
); );
} }
canvas.drawCircle(
Offset(data.last.x + size.width, size.height - data.last.y * yScale),
1,
paint,
);
} }
@override @override
@ -165,15 +203,19 @@ class _PointGraphPainter extends CustomPainter {
} }
class _LineGraphPainter extends CustomPainter { class _LineGraphPainter extends CustomPainter {
final List<Point<double>> data; _LineGraphPainter({
required this.data,
required this.graphStroke,
});
_LineGraphPainter({required this.data}); final List<Point<double>> data;
final double graphStroke;
@override @override
void paint(Canvas canvas, Size size) { void paint(Canvas canvas, Size size) {
final paint = Paint() final paint = Paint()
..style = PaintingStyle.stroke ..style = PaintingStyle.stroke
..strokeWidth = 1.5 ..strokeWidth = graphStroke
..color = Colors.white; ..color = Colors.white;
Path path = Path(); Path path = Path();
// Find the maximum y value in the data // Find the maximum y value in the data