Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to draw rolling dynamic real-time line graph? #109

Closed
gitjohnmoon1234 opened this issue Nov 12, 2019 · 6 comments
Closed

How to draw rolling dynamic real-time line graph? #109

gitjohnmoon1234 opened this issue Nov 12, 2019 · 6 comments

Comments

@gitjohnmoon1234
Copy link

First of all,thanks for this project.I want to draw real-time polylines with auto roll effect,the code is as follows.When I change the frequency of drawing to slow,The value shown in the chart is correct.but with animation. i don't like the animation,but i don't know how to remove it.

ezgif com-video-to-gif

When I change the drawing frequency to fast,The drawing area of the chart shows the wrong value,It will be much smaller than the actual value.

002com-resize

the code:

  • cupertino_icons: ^0.1.2

  • fl_chart: ^0.4.1

  • 1

`void main() => runApp(MyApp());

class MyApp extends StatelessWidget {
// This widget is the root of your application.
@OverRide
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
primarySwatch: Colors.blue,
),
home: MyHomePage(title: 'testdata'),
);
}
}

class MyHomePage extends StatefulWidget {
MyHomePage({Key key, this.title}) : super(key: key);

final String title;

@OverRide
_MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State {
@OverRide
Widget build(BuildContext context) {
return Scaffold(
appBar: new AppBar(title: Text(widget.title)),
body: SafeArea(
child: LineChartSample1(),
),
);
}
}
`

  • 2

`import 'dart:async';

import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';

class LineChartSample1 extends StatefulWidget {
@OverRide
State createState() => LineChartSample1State();
}

class LineChartSample1State extends State {
bool isShowingMainData;

StreamController controller;

final timeout = const Duration(seconds: 1);
final ms = const Duration(milliseconds: 1);
Timer timer;
double x, y;
final List jj = new List();
final double duration = 0.4; //change this to change frequencey (second)
final double windows = 5.0; //the display windows size (second)

@OverRide
void initState() {
super.initState();

controller = StreamController();
controller.stream.distinct().listen((LineTouchResponse response) {});

isShowingMainData = true;
x = 0;
y = 0;
start(duration);
for (int i = 0; i < (windows / duration); i++) jj.add(0);

}

void start([double seconds]) {
var duration = seconds == null ? timeout : ms * seconds * 1000.0;
timer = Timer.periodic(duration, handleTimeout);
}

void handleTimeout(Timer timer) {
print("sdfsdfsdf ${x.toStringAsFixed(2)} s and $y \r\n");
x += duration;
setState(() {
//y = random.nextInt(100);
y += 5;
if (y >= 20) y = 0;
});
}

@OverRide
Widget build(BuildContext context) {
return AspectRatio(
aspectRatio: 1.23,
child: Container(
decoration: BoxDecoration(
// borderRadius: const BorderRadius.all(Radius.circular(18)),
gradient: LinearGradient(
colors: const [
Color(0xff2c274c),
Color(0xff46426c),
],
begin: Alignment.bottomCenter,
end: Alignment.topCenter,
)),
child: Stack(
children: [

        Column(
          crossAxisAlignment: CrossAxisAlignment.stretch,
          children: <Widget>[
            const SizedBox(
              height: 37,
            ),
            const SizedBox(
              height: 37,
            ),
            Expanded(
              child: Padding(
                padding: const EdgeInsets.only(right: 16.0, left: 6.0),
                // child: FlChart(
                //   swapAnimationDuration: Duration(milliseconds: 250),
                //   chart: LineChart(
                //     //isShowingMainData ? sampleData1() : sampleData2(),
                //     sampleData(),
                //   ),
                // ),

                 child: LineChart(
                    //isShowingMainData ? sampleData1() : sampleData2(),
                    sampleData(),
                  ),
              
              ),
            ),
            const SizedBox(
              height: 10,
            ),
          ],
        ),
        // IconButton(
        //   icon: Icon(
        //     Icons.refresh,
        //     color: Colors.white.withOpacity(isShowingMainData ? 1.0 : 0.5),
        //   ),
        //   onPressed: () {
        //     setState(() {
        //       isShowingMainData = !isShowingMainData;
        //     });
        //   },
        // )
      ],
    ),
  ),
);

}

LineChartData sampleData() {
return LineChartData(
lineTouchData: const LineTouchData(enabled: false),
gridData: const FlGridData(
show: false,
),
titlesData: FlTitlesData(
bottomTitles: SideTitles(
showTitles: false,
reservedSize: 5,
textStyle: TextStyle(
color: const Color(0xff72719b),
fontWeight: FontWeight.bold,
fontSize: 16,
),
margin: 10,
getTitles: (value) {
switch (value.toInt()) {
case 2:
return 'SEPT';
case 7:
return 'OCT';
case 12:
return 'DEC';
}
return '';
},
),
leftTitles: SideTitles(
showTitles: true,
textStyle: TextStyle(
color: const Color(0xff75729e),
fontWeight: FontWeight.bold,
fontSize: 10,
),
getTitles: (value) {
switch (value.toInt()) {
case 5:
return '5';
case 10:
return '10';
case 15:
return '15';
case 20:
return '20';
}
return '';
},
margin: 1,
reservedSize: 15,
),
),
borderData: FlBorderData(
show: true,
border: Border(
bottom: BorderSide(
color: const Color(0xff4e4965),
width: 4,
),
left: BorderSide(
color: Colors.transparent,
),
right: BorderSide(
color: Colors.transparent,
),
top: BorderSide(
color: const Color(0xff4e49f5),
width: 5,
),
)),
minX: 0,
maxX: windows,
maxY: 20,
minY: 0,
lineBarsData: linesBarData(y),
);
}

List linesBarData(double j) {
List data0 = new List();
jj.add(j);
jj.removeAt(0);

double k = 0;
for (int i = 0; i < (windows / duration); i++) {
  data0.add(FlSpot(k.toDouble(), jj.elementAt(i)));
  k += duration;
}
return [
  LineChartBarData(
    spots: data0,
    isCurved: true,
    curveSmoothness: 0.0,
    preventCurveOverShooting: true,
    colors: [
      Colors.yellow,
    ],
    barWidth: 1,
    isStrokeCapRound: false,
    dotData: FlDotData(
      show: false,
    ),
    belowBarData: BarAreaData(
      show: false,
    ),
  ),
];

}

@OverRide
void dispose() {
super.dispose();
controller.close();
}
}
`

@imaNNeo
Copy link
Owner

imaNNeo commented Nov 12, 2019

Please provide a screen recorded video, this video is not clear.
and please write your codes formatted in a code block, then I will check it.
Thanks!

@gitjohnmoon1234
Copy link
Author

Ok,thanks tell me this link.

video 1

001.mp4

video 2

002.mp4

the code is

import 'package:flutter/material.dart';
import 'line_chart_sample1.dart';

void main() => runApp(MyApp());
class MyApp extends StatelessWidget {
  // This widget is the root of your application.
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'Flutter Demo',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: MyHomePage(title: 'testdata'),
    );
  }
}

class MyHomePage extends StatefulWidget {
  MyHomePage({Key key, this.title}) : super(key: key);

  final String title;

  @override
  _MyHomePageState createState() => _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: new AppBar(title: Text(widget.title)),
      body: SafeArea(
        child: LineChartSample1(),
      ),
    );
  }
}

import 'dart:async';

import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/material.dart';

class LineChartSample1 extends StatefulWidget {
  @override
  State<StatefulWidget> createState() => LineChartSample1State();
}

class LineChartSample1State extends State<LineChartSample1> {
  bool isShowingMainData;

  StreamController<LineTouchResponse> controller;

  final timeout = const Duration(seconds: 1);
  final ms = const Duration(milliseconds: 1);
  Timer timer;
  double x, y;
  final List<double> jj = new List<double>();
  final double duration = 0.04;  // (unit :second) modify this to change refersh frequency 
  final double windows = 5.0;    //(unit :second) modify this to change windows size 

  @override
  void initState() {
    super.initState();

    controller = StreamController();
    controller.stream.distinct().listen((LineTouchResponse response) {});

    isShowingMainData = true;
    x = 0;
    y = 0;
    start(duration);
    for (int i = 0; i < (windows / duration); i++) jj.add(0);
  }

  void start([double seconds]) {
    var duration = seconds == null ? timeout : ms * seconds * 1000.0;
    timer = Timer.periodic(duration, handleTimeout);
  }

  void handleTimeout(Timer timer) {
    print("sdfsdfsdf ${x.toStringAsFixed(2)} s  and $y  \r\n");
    x += duration;
    setState(() {
      //y = random.nextInt(100);
      y += 5;
      if (y >= 20) y = 0;
    });
  }

  @override
  Widget build(BuildContext context) {
    return AspectRatio(
      aspectRatio: 1.23,
      child: Container(
        decoration: BoxDecoration(
            // borderRadius: const BorderRadius.all(Radius.circular(18)),
            gradient: LinearGradient(
          colors: const [
            Color(0xff2c274c),
            Color(0xff46426c),
          ],
          begin: Alignment.bottomCenter,
          end: Alignment.topCenter,
        )),
        child: Stack(
          children: <Widget>[
            Column(
              crossAxisAlignment: CrossAxisAlignment.stretch,
              children: <Widget>[
                const SizedBox(
                  height: 37,
                ),
                const SizedBox(
                  height: 37,
                ),
                Expanded(
                  child: Padding(
                    padding: const EdgeInsets.only(right: 16.0, left: 6.0),
                    // child: FlChart(
                    //   swapAnimationDuration: Duration(milliseconds: 250),
                    //   chart: LineChart(
                    //     //isShowingMainData ? sampleData1() : sampleData2(),
                    //     sampleData(),
                    //   ),
                    // ),

                     child: LineChart(
                        //isShowingMainData ? sampleData1() : sampleData2(),
                        sampleData(),
                      ),
                  
                  ),
                ),
                const SizedBox(
                  height: 10,
                ),
              ],
            ),
            // IconButton(
            //   icon: Icon(
            //     Icons.refresh,
            //     color: Colors.white.withOpacity(isShowingMainData ? 1.0 : 0.5),
            //   ),
            //   onPressed: () {
            //     setState(() {
            //       isShowingMainData = !isShowingMainData;
            //     });
            //   },
            // )
          ],
        ),
      ),
    );
  }

  LineChartData sampleData() {
    return LineChartData(
      lineTouchData: const LineTouchData(enabled: false),
      gridData: const FlGridData(
        show: false,
      ),
      titlesData: FlTitlesData(
        bottomTitles: SideTitles(
          showTitles: false,
          reservedSize: 5,
          textStyle: TextStyle(
            color: const Color(0xff72719b),
            fontWeight: FontWeight.bold,
            fontSize: 16,
          ),
          margin: 10,
          getTitles: (value) {
            switch (value.toInt()) {
              case 2:
                return 'SEPT';
              case 7:
                return 'OCT';
              case 12:
                return 'DEC';
            }
            return '';
          },
        ),
        leftTitles: SideTitles(
          showTitles: true,
          textStyle: TextStyle(
            color: const Color(0xff75729e),
            fontWeight: FontWeight.bold,
            fontSize: 10,
          ),
          getTitles: (value) {
            switch (value.toInt()) {
              case 5:
                return '5';
              case 10:
                return '10';
              case 15:
                return '15';
              case 20:
                return '20';
            }
            return '';
          },
          margin: 1,
          reservedSize: 15,
        ),
      ),
      borderData: FlBorderData(
          show: true,
          border: Border(
            bottom: BorderSide(
              color: const Color(0xff4e4965),
              width: 4,
            ),
            left: BorderSide(
              color: Colors.transparent,
            ),
            right: BorderSide(
              color: Colors.transparent,
            ),
            top: BorderSide(
              color: const Color(0xff4e49f5),
              width: 5,
            ),
          )),
      minX: 0,
      maxX: windows,
      maxY: 20,
      minY: 0,
      lineBarsData: linesBarData(y),
    );
  }

  List<LineChartBarData> linesBarData(double j) {
    List<FlSpot> data0 = new List<FlSpot>();
    jj.add(j);
    jj.removeAt(0);

    double k = 0;
    for (int i = 0; i < (windows / duration); i++) {
      data0.add(FlSpot(k.toDouble(), jj.elementAt(i)));
      k += duration;
    }
    return [
      LineChartBarData(
        spots: data0,
        isCurved: false,
        curveSmoothness: 0.0,
        preventCurveOverShooting: true,
        colors: [
          Colors.yellow,
        ],
        barWidth: 1,
        isStrokeCapRound: false,
        dotData: FlDotData(
          show: false,
        ),
        belowBarData: BarAreaData(
          show: false,
        ),
      ),
    ];
  }

  @override
  void dispose() {
    super.dispose();
    controller.close();
  }
}

@gitjohnmoon1234
Copy link
Author

You can download these two video on my git , thanks very much @imaNNeoFighT

@imaNNeo
Copy link
Owner

imaNNeo commented Nov 12, 2019

Ok I will check it.

@imaNNeo
Copy link
Owner

imaNNeo commented Nov 14, 2019

try to set swapAnimationDuration: Duration.zero in your LineChart widget to disable the animations.

@gitjohnmoon1234
Copy link
Author

Thanks a lot for your support.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants