0
votes

I'm trying to make a simple pie chart but I'm having trouble using future data in the factory constructor. The error message says:

2 positional argument(s) expected, but 1 found.

The argument type 'Future<List<Series<LinearSales, int>>>' can't be assigned to the parameter type 'List<Series<dynamic, dynamic>>'.

This is the code:

/// Simple pie chart example.
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:flutter/material.dart';
import 'package:testingflutterapp/models/budget.dart';
import 'package:testingflutterapp/services/db.dart';

class SimplePieChart extends StatefulWidget {
  final List<charts.Series> seriesList;
  final bool animate;
  SimplePieChart(this.seriesList, this.animate);
  @override
  _SimplePieChartState createState() {
    return _SimplePieChartState(this.seriesList, this.animate);
  }
}

class _SimplePieChartState extends State<SimplePieChart> {
  List<charts.Series> seriesList;
  final bool animate;
  _SimplePieChartState(this.seriesList, this.animate);

  /// Creates a [PieChart] with sample data and no transition.
  factory _SimplePieChartState.withSampleData(int goal) {
    return _SimplePieChartState(
      _createSampleData(goal),
      animate: false,
      // Disable animations for image tests.
    );
  }

  @override
  Widget build(BuildContext context) {
    return new charts.PieChart(seriesList, animate: animate);
  }

  Future<Budget> giveData(int goal) async {
    List<Budget> _tasks = [];
    List<Map<String, dynamic>> _results =
        await DB.rawQuery('SELECT * FROM budget WHERE budget.id="$goal";');
    _tasks = _results.map((item) => Budget.fromMap(item)).toList();
    Budget budgetToDisplay = _tasks[0];
    return budgetToDisplay;
  }

  Future<double> giveDataSum(int goalID) async {
    List<Budget> _tasks = [];
    List<Map<String, dynamic>> _results = await DB.rawQuery(
        'SELECT sum(value) AS value FROM (SELECT budget_items.* FROM budget_items INNER JOIN budget_items_list ON budget_items_list.budget_items_id=budget_items.id INNER JOIN budget ON budget.id=budget_items_list.budget_id WHERE budget.id="$goalID");');
    _tasks = _results.map((item) => Budget.fromMap(item)).toList();
    double budgetToDisplay = _tasks[0].goal;
    return budgetToDisplay;
  }

  /// Create one series with sample hard coded data.
  Future<List<charts.Series<LinearSales, int>>> _createSampleData(
      int goal) async {
    // Calculate percentages
    //get goal value
    Budget budgetDisplay = await giveData(goal);
    double goalValue = budgetDisplay.goal;
    double keepValue = await giveDataSum(goal);
    double graphLine = goalValue - keepValue;
    final data = [
      new LinearSales(0, keepValue as int), // value saved = x
      new LinearSales(1, graphLine as int), // value to save = goal - x
    ];

    return [
      new charts.Series<LinearSales, int>(
        id: 'Sales',
        domainFn: (LinearSales sales, _) => sales.year,
        measureFn: (LinearSales sales, _) => sales.sales,
        data: data,
      )
    ];
  }
}

/// Sample linear data type.
class LinearSales {
  final int year;
  final int sales;

  LinearSales(this.year, this.sales);
}

EDIT: I was able to fix this with a Future Builder. My code with the changes:

import 'package:charts_flutter/flutter.dart' as charts;
import 'package:charts_flutter/flutter.dart';
import 'package:flutter/material.dart';
import 'package:testingflutterapp/models/budget.dart';
import 'package:testingflutterapp/services/db.dart';

// ignore: must_be_immutable
class SimplePieChart extends StatefulWidget {
  SimplePieChart(this.goal);

  int goal;
  @override
  _SimplePieChartState createState() {
    return _SimplePieChartState(this.goal);
  }
}

class _SimplePieChartState extends State<SimplePieChart> {

  List<charts.Series> seriesList;
  List<charts.Series> seriesListNew;
  bool animate;
  int goal;
  _SimplePieChartState(this.goal);

  /// Creates a [PieChart] with sample data and no transition.

  @override
  Widget build(BuildContext context) {
    return FutureBuilder<List<charts.Series<LinearSales, int>>>(
        future: _createSampleData(goal),
        builder: (context, AsyncSnapshot<List<charts.Series<LinearSales, int>>> seriesList) {
          if (seriesList.hasData) {
            return charts.PieChart(
                seriesList.data,
                animate: false);
          } else {
            return CircularProgressIndicator();
          }
        }
    );
  }

  Future<Budget> giveData(int goal) async {
    List<Budget> _tasks = [];
    List<Map<String, dynamic>> _results =
        await DB.rawQuery('SELECT * FROM budget WHERE budget.id="$goal";');
    _tasks = _results.map((item) => Budget.fromMap(item)).toList();
    Budget budgetToDisplay = _tasks[0];
    return budgetToDisplay;
  }

  Future<double> giveDataSum(int goalID) async {
    List<Budget> _tasks = [];
    List<Map<String, dynamic>> _results = await DB.rawQuery(
        'SELECT sum(value) AS value FROM (SELECT budget_items.* FROM budget_items INNER JOIN budget_items_list ON budget_items_list.budget_items_id=budget_items.id INNER JOIN budget ON budget.id=budget_items_list.budget_id WHERE budget.id="$goalID");');
    _tasks = _results.map((item) => Budget.fromMap(item)).toList();
    double budgetToDisplay = _tasks[0].goal;
    String x = _results[0].values.toString().replaceAll(new RegExp(r'[\(,\)]'), "");
    double y = double.parse(x);
    return y;
  }

  /// Create one series with sample hard coded data.
  Future<List<charts.Series<LinearSales, int>>> _createSampleData(int goal) async {

    // Calculate percentages
    //get goal value
    Budget budgetDisplay = await giveData(goal);

    double goalValue = budgetDisplay.goal;

    double keepValue = await giveDataSum(goal);

    double graphLine = goalValue - keepValue;
    //print(graphLine.round());
    final data = [
      new LinearSales(0, keepValue.round()), // value saved = x
      new LinearSales(1, graphLine.round()), // value to save = goal - x
    ];


    return [
      new charts.Series<LinearSales, int>(
        id: 'Sales',
        domainFn: (LinearSales sales, _) => sales.year,
        measureFn: (LinearSales sales, _) => sales.sales,
        data: data,
      )
    ];
    //return seriesList;
  }
}

/// Sample linear data type.
class LinearSales {
  final int year;
  final int sales;

  LinearSales(this.year, this.sales);
}```
1
_SimplePieChartState should NOT have a constructor. Use widget.seriesList (for example) to access the members declared in the StatefulWidget.Alberto Miola

1 Answers

0
votes

Your problems are here

return _SimplePieChartState(
  _createSampleData(goal),
  animate: false,
  // Disable animations for image tests.
);
  1. _createSampleData returns a Future so you have to await it in order to obtain List<Series<dynamic, dynamic>>, factory constructors can't be async so you will need to rethink your logic

  2. _SimplePieChartState has 2 positional parameters and you're using animate parameter as named. It should be false and not animate: false