How to display json data in flutter charts

9,914

Solution 1

I think what you want is:

import 'dart:async';
import 'dart:convert';

import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:charts_flutter/flutter.dart' as charts;

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      home: new MyHomePage(),
    );
  }
}

class MyHomePage extends StatefulWidget {
  @override
  _MyHomePageState createState() => new _MyHomePageState();
}

class _MyHomePageState extends State<MyHomePage> {
  List data;
  Timer timer;

  makeRequest() async {
    var response = await http.get(
      'http://localhost/werkzeug/public/api/data_tool1',
      headers: {'Accept': 'application/json'},
    );

    setState(() {
      data = json.decode(response.body);
    });
  }

  @override
  void initState() {
    super.initState();
    timer = new Timer.periodic(new Duration(seconds: 2), (t) => makeRequest());
  }

  @override
  void dispose() {
    timer.cancel();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return new Scaffold(
      appBar: new AppBar(
        title: new Text('Tool Data'),
      ),
      body: data == null ? CircularProgressIndicator() : createChart(),
    );
  }

  charts.Series<LiveWerkzeuge, String> createSeries(String id, int i) {
    return charts.Series<LiveWerkzeuge, String>(
      id: id,
      domainFn: (LiveWerkzeuge wear, _) => wear.wsp,
      measureFn: (LiveWerkzeuge wear, _) => wear.belastung,
      // data is a List<LiveWerkzeuge> - extract the information from data
      // could use i as index - there isn't enough information in the question
      // map from 'data' to the series
      // this is a guess
      data: [
        LiveWerkzeuge('WSP1', data[i]['temp1']),
        LiveWerkzeuge('WSP2', data[i]['temp2']),
        LiveWerkzeuge('WSP3', data[i]['temp3']),
        LiveWerkzeuge('WSP4', data[i]['temp4']),
        LiveWerkzeuge('WSP5', data[i]['temp5']),
        LiveWerkzeuge('WSP6', data[i]['temp6']),
        LiveWerkzeuge('WSP7', data[i]['temp7']),
        LiveWerkzeuge('WSP8', data[i]['temp8']),
      ],
    );
  }

  Widget createChart() {
    // data is a List of Maps
    // each map contains at least temp1 (tool 1) and temp2 (tool 2)
    // what are the groupings?

    List<charts.Series<LiveWerkzeuge, String>> seriesList = [];

    for (int i = 0; i < data.length; i++) {
      String id = 'WZG${i + 1}';
      seriesList.add(createSeries(id, i));
    }

    return new charts.BarChart(
      seriesList,
      barGroupingType: charts.BarGroupingType.grouped,
    );
  }
}

class LiveWerkzeuge {
  final String wsp;
  final int belastung;

  LiveWerkzeuge(this.wsp, this.belastung);
}

Solution 2

Change:

data = json.decode(response.body);

to:

data = json.decode(utf8.decode(response.bodyBytes)); //for special characters
Share:
9,914
Eti
Author by

Eti

Mechanical Engineering student interested in Programming.

Updated on December 05, 2022

Comments

  • Eti
    Eti over 1 year

    I'm still new to flutter and I've been trying to display some data from a http request in a Bar-chart. I couldn't find any example for this. I hope some of you guys can help :)

    I though of using this Chart from the online gallery. I just changed the name of the classes for my app:

    import 'package:flutter/material.dart';
    import 'package:charts_flutter/flutter.dart' as charts;
    
    class SimpleSeriesLegend extends StatelessWidget {
      final List<charts.Series> seriesList;
      final bool animate;
    
      SimpleSeriesLegend(this.seriesList, {this.animate});
    
      factory SimpleSeriesLegend.withSampleData() {
        return new SimpleSeriesLegend(
          _createSampleData(),
          // Disable animations for image tests.
          animate: false,
        );
      }
    
      @override
      Widget build(BuildContext context) {
        return new charts.BarChart(
          seriesList,
          animate: animate,
          barGroupingType: charts.BarGroupingType.grouped,
          // Add the series legend behavior to the chart to turn on series legends.
          // By default the legend will display above the chart.
          behaviors: [new charts.SeriesLegend()],
        );
      }
    
      /// Create series list with multiple series
      static List<charts.Series<LiveWerkzeuge, String>> _createSampleData() {
        final tool1Data = [
          new LiveWerkzeuge ('WSP1', 5),
          new LiveWerkzeuge ('WSP2', 25),
          new LiveWerkzeuge ('WSP3', 80),
          new LiveWerkzeuge ('WSP4', 75),
          new LiveWerkzeuge ('WSP5', 65),
          new LiveWerkzeuge ('WSP6', 55),
          new LiveWerkzeuge ('WSP7', 70),
          new LiveWerkzeuge ('WSP8', 90),
        ];
        
        return [
          new charts.Series<LiveWerkzeuge, String>(
            id: 'WZG1',
            domainFn: (LiveWerkzeuge wear, _) => wear.wsp,
            measureFn: (LiveWerkzeuge wear, _) => wear.belastung,
            data: tool1Data,
          ),
        ];
      }
    
    }
    /// Sample ordinal data type.
    class LiveWerkzeuge {
      final String wsp;
      final int belastung;
    
      LiveWerkzeuge(this.wsp, this.belastung);
    }
    This is the only way it would show my code correctly, sorry.

    This is a simple code I found to access and display the data in a ListView and update automatically. I just wanted to learn how to do this and it worked for me:

    import 'dart:async';
    import 'dart:convert';
    
    import 'package:flutter/material.dart';
    
    import 'package:http/http.dart' as http;
    
    void main() => runApp(new MyApp());
    
    class MyApp extends StatelessWidget {
      // This widget is the root of your application.
      @override
      Widget build(BuildContext context) {
        return new MaterialApp(
          home: new MyHomePage(),
        );
      }
    }
    
    class MyHomePage extends StatefulWidget {
      @override
      _MyHomePageState createState() => new _MyHomePageState();
    }
    
    class _MyHomePageState extends State<MyHomePage> {
      String url = 'http://localhost/werkzeug/public/api/data_tool1';
      List data;
      Timer timer;
    
      Future<String> makeRequest() async {
        var response = await http
            .get(Uri.encodeFull(url), headers: {"Accept": "application/json"});
    
        setState(() {
          var extractdata = JSON.decode(response.body);
          data = extractdata;
        });
      }
    
      @override
      void initState() {
        super.initState();
        timer = new Timer.periodic(new Duration(seconds: 2), (Timer timer) async {
          this.makeRequest();
        });
      }
    
      @override
      void dispose() {
        super.dispose();
        timer.cancel();
      }
    
      @override
      Widget build(BuildContext context) {
        return new Scaffold(
            appBar: new AppBar(
              title: new Text('Tool Data'),
            ),
            body: new ListView.builder(
                itemCount: data == null ? 0 : data.length,
                itemBuilder: (BuildContext context, int i) {
                  return new ListTile(
                    title: new Text('Tool 1 Temperature is : ''${data[i]["temp1"]}' ' and tool 2 is: ''${data[i]["temp2"]}'),
                  );
                }
            )
        );
      }
    }

    Now I would like to combine this two.

    This is how the data looks like:

    [{"timestamp":"2018-06-29 14:39:18","rpm":0,"rpm_filter":0,"accel":0,"temp1":104,"temp2":746,"temp3":134,"temp4":77,"temp5":0,"temp6":0,"temp7":0,"temp8":0,"DMS1":0,"DMS2":0,"DMS3":0,"DMS4":0,"batt":0,"shock":0,"shock_accel":0,"shock_degxy":0,"shock_degxz":0,"error":0,"connection_id":0,"Wear1":0,"Wear2":0,"Wear3":0,"Wear4":0,"Wear5":0,"Wear6":0,"Wear7":0,"Wear8":0,"standzeit1":0,"standzeit2":0,"standzeit3":0,"standzeit4":0,"standzeit5":0,"standzeit6":0,"standzeit7":0,"standzeit8":0}]

    New Exeption:

    I/flutter ( 7654): ══╡ EXCEPTION CAUGHT BY WIDGETS LIBRARY ╞═══════════════════════════════════════════════════════════ I/flutter ( 7654): The following RangeError was thrown building MyHomePage(dirty, state: _MyHomePageState#9477b): I/flutter ( 7654): RangeError (index): Invalid value: Only valid value is 0: 1 I/flutter ( 7654): I/flutter ( 7654): When the exception was thrown, this was the stack: I/flutter ( 7654): #0 List.[] (dart:core/runtime/libgrowable_array.dart:141:60) I/flutter ( 7654): #1 _MyHomePageState.createSeries (file:///Users/Eti/AndroidStudioProjects/test_json_app/lib/main.dart:71:35) I/flutter ( 7654): #2 _MyHomePageState.createChart (file:///Users/Eti/AndroidStudioProjects/test_json_app/lib/main.dart:89:7) I/flutter ( 7654): #3 _MyHomePageState.build (file:///Users/Eti/AndroidStudioProjects/test_json_app/lib/main.dart:57:58) I/flutter ( 7654): #4 StatefulElement.build (package:flutter/src/widgets/framework.dart:3743:27) I/flutter ( 7654): #5 ComponentElement.performRebuild (package:flutter/src/widgets/framework.dart:3655:15) I/flutter ( 7654): #6 Element.rebuild (package:flutter/src/widgets/framework.dart:3508:5) I/flutter ( 7654): #7 BuildOwner.buildScope (package:flutter/src/widgets/framework.dart:2255:33) I/flutter ( 7654): #8 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding&WidgetsBinding.drawFrame (package:flutter/src/widgets/binding.dart:626:20) I/flutter ( 7654): #9 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding&PaintingBinding&RendererBinding._handlePersistentFrameCallback (package:flutter/src/rendering/binding.dart:208:5) I/flutter ( 7654): #10 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._invokeFrameCallback (package:flutter/src/scheduler/binding.dart:990:15) I/flutter ( 7654): #11 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding.handleDrawFrame (package:flutter/src/scheduler/binding.dart:930:9) I/flutter ( 7654): #12 _WidgetsFlutterBinding&BindingBase&GestureBinding&ServicesBinding&SchedulerBinding._handleDrawFrame (package:flutter/src/scheduler/binding.dart:842:5) I/flutter ( 7654): #13 _invoke (dart:ui/hooks.dart:120:13) I/flutter ( 7654): #14 _drawFrame (dart:ui/hooks.dart:109:3) I/flutter ( 7654): ════════════════════════════════════════════════════════════════════════════════════════════════════ I/flutter ( 7654): Another exception was thrown: RangeError (index): Invalid value: Only valid value is 0: 1 I/flutter ( 7654): Another exception was thrown: RangeError (index): Invalid value: Only valid value is 0: 1