1
votes

I am using charts_flutter in my Flutter app and currently I am trying to implement this chart: https://google.github.io/charts/flutter/example/combo_charts/scatter_plot_line.

This is my Series for the line in the chart:

charts.Series(
    measureFn: ((dynamic number, _) async => await analyticsLinearRegression.predict(number * 1.0)),
    domainFn: ((dynamic number, _) async => await analyticsLinearRegression.predict(number * 1.0)),
    colorFn: (dynamic number, _) => charts.ColorUtil.fromDartColor(Colors.blue[900]),
    id: "linearRegression",
    data: [
        0,
        highestX,
    ],
)..setAttribute(charts.rendererIdKey, "linearRegressionLine")

The problem is obvious: The argument type 'Future<double> Function(dynamic, int)' can't be assigned to the parameter type 'num Function(dynamic, int)'.

I understand where the problem is, but the function analyticsLinearRegression.predict returns Future<double> and not double, I can't change that.

So how can I use the data from the analyticsLinearRegression.predict function here for the Series of the line?

2

2 Answers

0
votes

You need to do your data processing before you call your build for your chart. Call analyticsLinearRegression.predict in an async function in the StatefulWidget class that contains your chart. Await the return of your async function and then call setState() and build your chart passing the completed data to the chart.

0
votes

Complementing @Scott's answer, you should do something like this:

class YourWidget extends StatelessWidget {
    // Create a future inside your widget to store the computations
    Future<List<double>> _future;

    // Do your asynchronous computations inside a asynchronous method
    Future<List<double>> _compute() async {
        double x = await analyticsLinearRegression.predict(number * 1.0);
        double y = await analyticsLinearRegression.predict(number * 1.0);
        return [x, y];
    }
 
    // When creating the widget, assign the future to the async method result
    @override
    void initState() {
        super.initState();
        _future = _compute();
    }

    // When building, use a FutureBuilder to avoid blocking the screen
    @override
    Widget build(BuildContext context) {
        return FutureBuilder(
            // Wait for the computation of the created future
            future: _future,
            builder: (context, snapshot) {
                // If the computation is not ready yet, return a progress indicator
                if (snapshot.connectionState == ConnectionState.waiting)
                    return Center(child: CircularProgressIndicator());
                
                // If it's ready, display it
                final List<double> result = snapshot.data;
                return charts.Series(
                    measureFn: (dynamic number, _) => result[0],
                    domainFn: (dynamic number, _) => result[1],
                    colorFn: (dynamic number, _) => charts.ColorUtil.fromDartColor(Colors.blue[900]),
                    id: "linearRegression",
                    data: [0, highestX],
                );
            },
        );
    }
}