如何使动态图表变得扑朔迷离? [英] how to make dynamic chart in flutter?

查看:56
本文介绍了如何使动态图表变得扑朔迷离?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

您好,我试图制作一个简单的图表,在x轴上显示日期,在Y轴上显示数据.当我按下按钮时,当前日期的数据增加.第一个目标是通过以下代码完成的.但是现在我不知道如何使图表更加动态,我希望统计每一天的按下按钮的统计信息.我不知道如何为每一天动态地添加新的数据列.

Hello I tried to make a simple chart in flutter with date in x axis and data in Y axis. When I push a button data is increase for the current date. first goal is completed with the code bellow. But now I don't know how to make chart more dynamic, I want statistic of my pressed button for each new day. I don't know how to add dynamicaly a new column of data for each new days.

import 'package:flutter/material.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:intl/intl.dart';
void main() => runApp(new MyApp());

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  final String title;

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

class ClicksPerYear {
  final String year;
  final int clicks;
  final charts.Color color;

  ClicksPerYear(this.year, this.clicks, Color color)
      : this.color = new charts.Color(
      r: color.red, g: color.green, b: color.blue, a: color.alpha);
}

class _MyHomePageState extends State<MyHomePage> {
  int _counter = 0;
  var currentTime;
  void _incrementCounter() {
    setState(() {
      _counter++;
    });
  }

  @override
  Widget build(BuildContext context) {
    var data = [

      new ClicksPerYear('2015', 3, Colors.red),
      new ClicksPerYear('2016', 7, Colors.orange),
      new ClicksPerYear('2017', 42, Colors.yellow),
      new ClicksPerYear('$currentTime', _counter, Colors.green),
    ];

    var series = [
      new charts.Series(
        domainFn: (ClicksPerYear clickData, _) => clickData.year,
        measureFn: (ClicksPerYear clickData, _) => clickData.clicks,
        colorFn: (ClicksPerYear clickData, _) => clickData.color,
        id: 'Clicks',
        data: data,

      ),
    ];
    var chart = new charts.BarChart(
      series,
      animate: true,
    );

    var chartWidget = new Padding(
      padding: new EdgeInsets.all(32.0),
      child: new SizedBox(
        height: 200.0,
        child: chart,
      ),
    );

    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(
        child: new Column(
          mainAxisAlignment: MainAxisAlignment.center,
          children: <Widget>[
            new Text(
              'You have pushed the button this many times:',
            ),
            new Text(
              '$_counter',
              style: Theme.of(context).textTheme.display1,
            ),
            chartWidget,
          ],
        ),
      ),

      floatingActionButton: FloatingActionButton(
        onPressed: () {
          setState(() {
            DateTime now = DateTime.now();
            currentTime = DateFormat('dd/MM/yyyy').format(now);
            _incrementCounter();
          });
        },
        child: Icon(Icons.add,),

      ),

    );
  }
}

推荐答案

您共享的代码存在一些小问题.我试图修复它们,并根据您自己的代码准备更新的版本.查看以下提示:

There are some tiny issues with the codes you shared. I tried to fix them and prepare an updated version based on your own code. check out below tips:

您已经使用了颤动的初始示例提供的计数器.此计数器是父窗口小部件的成员变量,并且只有一个计数器可用.因此,您必须使其他栏变为静态!这似乎不太好.将其转换为List或Map即可解决,但最好将值保存在对象本身内.

You've used the counter provided by the initial example of flutter. this counter is a member variable of the parent widget and there is only one counter available. so you have to make the other bars static! which doesn't seem good. converting it to a List or Map will solve it but it's better to hold the value inside the object itself.

例如,假设您要在另一页中使用2016年数据.您必须从父窗口小部件获取数据并将其传递到新页面.但是,如果将点击保留在对象内部,则只需要传递对象本身即可.

e.g suppose you want to use 2016 data in another page. you have to get the data from the parent widget and pass it to a new page. But if you keep the clicks inside the object, you just need to pass the object itself.

数据列表是在构建方法的开头定义的.在这种情况下,每当小部件重新构建自身时,它都会启动数据列表.看起来不太好!该列表可用,并且应该对其进行任何更改.对其进行完善可能会删除之前的更改.

The data list is defined at the beginning of the build method. in this case, whenever the widget rebuilds itself, it will initiate the data list. which doesn't seem good! the list is available and any changes should be applied to it. refining it may remove the previous changes.

尽管将List类型用于数据变量没有问题,但我建议改为使用Map类型.如果要使用列表,则每当要对数据元素应用任何更改时,都需要在其中搜索并找到合适的元素.但是使用Map类型时,您可以只存储密钥并在以后使用.

Although there is no issue with using List type for data variable, I suggest using Map type instead. If you want to use List, whenever you want to apply any changes into the element of the data, you need to search through it and find the right element. But with Map type, you can just store the key and use it later.

签出更正后的代码,如果对此有任何疑问,请告诉我:

Check out the corrected code and let me know if you have any question about it:

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

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

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return new MaterialApp(
      title: 'Flutter Demo',
      theme: new ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: new MyHomePage(title: 'Flutter Demo Home Page'),
    );
  }
}

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

  final String title;

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

class ClicksPerYear {
  final String year;
  int clicks;
  final charts.Color color;

  ClicksPerYear(this.year, this.clicks, Color color)
      : this.color = new charts.Color(
            r: color.red, g: color.green, b: color.blue, a: color.alpha);

  incrementClick() {
    clicks++;
  }
}

class _MyHomePageState extends State<MyHomePage> {
  var currentTime = DateFormat('dd/MM/yyyy').format(DateTime.now());
  Map<String, ClicksPerYear> data;

  @override
  void initState() {
    data = {
      '2015': ClicksPerYear('2015', 3, Colors.red),
      '2016': ClicksPerYear('2016', 7, Colors.orange),
      '2017': ClicksPerYear('2017', 42, Colors.yellow),
      '$currentTime': ClicksPerYear('$currentTime', 0, Colors.green),
    };
    super.initState();
  }

  @override
  Widget build(BuildContext context) {
    var series = [
      new charts.Series(
          domainFn: (ClicksPerYear clickData, _) => clickData.year,
          measureFn: (ClicksPerYear clickData, _) => clickData.clicks,
          colorFn: (ClicksPerYear clickData, _) => clickData.color,
          id: 'Clicks',
          data: data.values.toList()),
    ];
    var chart = new charts.BarChart(
      series,
      animate: true,
    );

    var chartWidget = new Padding(
      padding: new EdgeInsets.all(32.0),
      child: new SizedBox(
        height: 200.0,
        child: chart,
      ),
    );

    return new Scaffold(
      appBar: new AppBar(
        title: new Text(widget.title),
      ),
      body: new Center(child: chartWidget),
      floatingActionButton: Row(
        mainAxisAlignment: MainAxisAlignment.end,
        children: <Widget>[
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: FloatingActionButton(
              onPressed: () {
                setState(() {
                  data.putIfAbsent(
                      '2012', () => ClicksPerYear('2012', 42, Colors.teal));
                });
              },
              child: Icon(
                Icons.add,
              ),
              backgroundColor: Colors.red,
            ),
          ),
          Padding(
            padding: const EdgeInsets.all(8.0),
            child: FloatingActionButton(
              onPressed: () {
                setState(() {
                  DateTime now = DateTime.now();
                  currentTime = DateFormat('dd/MM/yyyy').format(now);
                  data[currentTime].incrementClick();
                });
              },
              child: Icon(
                Icons.add,
              ),
            ),
          ),
        ],
      ),
    );
  }
}

这篇关于如何使动态图表变得扑朔迷离?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆