Flutter 颤振-将API用于带模型的图表

Flutter 颤振-将API用于带模型的图表,flutter,dart,charts,Flutter,Dart,Charts,这个问题我已经解决了将近三天了。已经在另一个问题中发布了,但得到的答案是负数。 让我把问题说清楚。 我想将使用模型的api数据放入chart Flatter,这是我的代码 首先是我的模特儿这里是我的年龄模特儿 年龄.飞镖 Ages agesFromJson(String str) => Ages.fromJson(json.decode(str)); String agesToJson(Ages data) => json.encode(data.toJson());

这个问题我已经解决了将近三天了。已经在另一个问题中发布了,但得到的答案是负数。 让我把问题说清楚。 我想将使用模型的api数据放入chart Flatter,这是我的代码 首先是我的模特儿这里是我的年龄模特儿

年龄.飞镖

  Ages agesFromJson(String str) => Ages.fromJson(json.decode(str));

  String agesToJson(Ages data) => json.encode(data.toJson());

  class Ages {
    Ages({
      this.entity,
      this.code,
      this.year,
      this.underAge15,
      this.age1564,
      this.age65Over,
    });

    String entity;
    String code;
    int year;
    String underAge15;
    String age1564;
    String age65Over;

    factory Ages.fromJson(Map<String, dynamic> json) => Ages(
          entity: json["entity"],
          code: json["code"],
          year: json["year"],
          underAge15: json["under_age_15"],
          age1564: json["age_15_64"],
          age65Over: json["age_65_over"],
        );

    Map<String, dynamic> toJson() => {
          "entity": entity,
          "code": code,
          "year": year,
          "under_age_15": underAge15,
          "age_15_64": age1564,
          "age_65_over": age65Over,
        };
  }
    class AgeCharts extends StatefulWidget {
      final String url;

      const AgeCharts({this.url});

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

    class _AgeChartsState extends State<AgeCharts> {
      var chart;
      @override
      void initState() {
        // TODO: implement initState
        super.initState();
      }

      @override
      Widget build(BuildContext context) {
        print(widget.url);
        return SafeArea(
          child: Scaffold(
            appBar: AppBar(
              title: Text('Japanese Age Working Populations'),
            ),
            body: Container(
              height: 400,
              child: FutureBuilder<List>(
                future: getChartData(widget),
                builder: (context, dataapi) {
                  if (dataapi.hasError) print(dataapi.error);
                  print(dataapi);
                  return dataapi.hasData
                      ? ShowChart(
                          data: dataapi.data,
                        )
                      : Center(
                          child: CircularProgressIndicator(),
                        );
                },
              ),
            ),
          ),
        );
      }
    }
结果我犯了这样一个错误

 type 'List<dynamic>' is not a subtype of type 'List<Ages>'
类型“List”不是类型“List”的子类型

请帮助我解决问题,代码中的问题:

  • 您正在将序列数据显式转换为
    charts.series

    完整的源代码,便于复制粘贴
    导入'dart:math'作为数学;
    导入“dart:convert”;
    将“package:http/http.dart”导入为http;
    进口“包装:颤振/材料.省道”;
    以图表形式导入“包:图表\颤振/颤振.省道”;
    void main(){
    runApp(
    材料聚丙烯(
    debugShowCheckedModeBanner:false,
    标题:“图表演示”,
    主页:
    年龄图表(url:'http://udacoding-task-api.herokuapp.com/api/charts'),
    ),
    );
    }
    //主部件
    类AgeCharts扩展StatefulWidget{
    最终字符串url;
    常量图表({this.url});
    @凌驾
    _AgeChartsState createState()=>\u AgeChartstate();
    }
    类_AgeChartsState扩展状态{
    var图;
    未来getChartData(小部件)异步{
    最终响应=等待http.get(widget.url);
    最终列表jsonData=jsonDecode(response.body)['data'];
    返回jsonData.map((数据)=>Ages.fromJson(数据)).toList();
    }
    @凌驾
    小部件构建(构建上下文){
    返回安全区(
    孩子:脚手架(
    appBar:appBar(
    标题:文本(“日本适龄工作人口”),
    ),
    主体:填充物(
    填充:边缘设置。全部(8.0),
    孩子:未来建设者(
    未来:getChartData(小部件),
    生成器:(上下文,dataapi){
    如果(dataapi.hasError)打印(dataapi.error);
    返回dataapi.hasData
    ?图表(数据:dataapi.data)
    :居中(子项:循环压缩机指示器());
    },
    ),
    ),
    ),
    );
    }
    }
    //图表
    类ShowChart扩展了无状态小部件{
    最终清单数据;
    显示图({this.data});
    静态列表\u createSampleData(dataAPI){
    返回[
    新图表系列(
    id:'未满15岁',
    颜色fn:(u,uu)=>charts.materialpalete.blue.shadedfault,
    区域颜色fn:(u,u)=>
    charts.MaterialPalette.blue.shadeDefault.lighter、,
    域fn:(Ages,)=>Ages.year,
    measureFn:(Ages,)=>double.parse(Ages.underAge15).round(),
    数据:dataAPI,
    ),
    新图表系列(
    id:'年龄1564',
    颜色fn:(u,uu)=>charts.materialpalete.red.shadedfault,
    区域颜色fn:(u,uu)=>charts.materialpalete.red.shadedfault.lighter,
    域fn:(Ages,)=>Ages.year,
    measureFn:(Ages,)=>double.parse(Ages.age1564.round(),
    数据:dataAPI,
    ),
    新图表系列(
    id:‘65岁以上’,
    颜色fn:(u,uu)=>charts.materialpalete.green.shadedfault,
    区域颜色fn:(u,u)=>
    charts.MaterialPalette.green.shadeDefault.lighter、,
    域fn:(Ages,)=>Ages.year,
    measureFn:(Ages,)=>double.parse(Ages.age65Over).round(),
    数据:dataAPI,
    ),
    ];
    }
    @凌驾
    小部件构建(构建上下文){
    返回容器(
    子:charts.LineChart(
    _createSampleData(数据),
    默认渲染器:
    新图表.lineRenderConfig(includeArea:true,stacked:true),
    动画:对,
    domainAxis:charts.NumericAxisSpec(
    tickProviderSpec:
    图表.BasicNumericTickProviderSpec(零界:false),
    ),
    ),
    );
    }
    }
    //领域
    班级年龄{
    年代({
    这个实体,
    这个代码,
    今年,,
    这是15岁以下,
    这是1564岁,
    这个,65岁以上,
    });
    字符串实体;
    字符串代码;
    国际年;
    15岁以下;
    字符串年龄1564;
    线年龄65岁以上;
    factory Ages.fromJson(映射json)=>Ages(
    实体:json[“实体”],
    代码:json[“代码”],
    年份:json[“年份”],
    15岁以下:json[“15岁以下”],
    age1564:json[“age_15_64”],
    age65Over:json[“age_65_over”],
    );
    映射到JSON()=>{
    “实体”:实体,
    “代码”:代码,
    “年”:年,
    “15岁以下”:15岁以下,
    “年龄15岁64岁”:1564岁,
    “65岁以上”:65岁以上,
    };
    }
    //资料
    math.Random=math.Random();
    最终地图数据={
    “状态”:正确,
    “消息”:“找到图表”,
    “数据”:List.generate(
    20,
    (索引)=>{
    “实体”:“日本”,
    “代码”:“JPN”,
    “年份”:1950+指数,
    “15岁以下”:(25000+random.nextInt(5000)).toString(),
    “age_15_64”:(40000+随机.nextInt(5000)).toString(),
    “年龄超过65岁”:(3000+随机.nextInt(2000)).toString(),
    }).toList(),
    };
    

    更新答案前: 试试这个:

    Future<List<Ages>> getChartData(widget) async {
      final response = await http.get(widget.url);
      return json.decode(response.body)['data'].map((jsonData) => Ages.fromJson(jsonData)).toList();
    }
    
    未来getChartData(小部件)异步{ 最终响应=等待http.get(widget.url); 返回json.decode(response.body)['data'].map((jsonData)=>Ages.fromJson(jsonData)).toList(); }

    我不是100%确定,因为我不知道您的JSON数据的结构。

    谢谢您的回答,我已经编辑了我的问题:D在我将api更改为您的答案后,我遇到了另一个错误,类型“List”不是类型“FutureOr”的子类型。我在您的代码中发现了3个主要问题。答案更新。我试过你上面的代码,使用数学随机,它可以生成。但当我将其更改为json时,它就变成了一个问题,出现了异常_CastError(类型“List”不是类型转换中类型“List”的子类型)。。顺便说一句,这是我获得api的地方。我更新了解决方案以使用您的真实数据集。
    {
    "status": true,
    "message": "Chart found",
    "data": [
        {
            "entity": "Japan",
            "code": "JPN",
            "year": 1950,
            "under_age_15": "29288.106",
            "age_15_64": "49447.555",
            "age_65_over": "4066.423"
        },
        {
            "entity": "Japan",
            "code": "JPN",
            "year": 1951,
            "under_age_15": "29652.515",
            "age_15_64": "50461.828",
            "age_65_over": "4201.922"
        },
       ]
     }
    
     type 'List<dynamic>' is not a subtype of type 'List<Ages>'
    
    charts.LineChart(
      _createSampleData(data),
      defaultRenderer: charts.LineRendererConfig(includeArea: true, stacked: true),
      animate: true,
      domainAxis: charts.NumericAxisSpec(
        tickProviderSpec: charts.BasicNumericTickProviderSpec(zeroBound: false),
      ),
    ),
    
    import 'dart:math' as math;
    import 'dart:convert';
    import 'package:http/http.dart' as http;
    
    import 'package:flutter/material.dart';
    import 'package:charts_flutter/flutter.dart' as charts;
    
    void main() {
      runApp(
        MaterialApp(
          debugShowCheckedModeBanner: false,
          title: 'Charts Demo',
          home:
              AgeCharts(url: 'http://udacoding-task-api.herokuapp.com/api/charts'),
        ),
      );
    }
    
    // MAIN WIDGET
    
    class AgeCharts extends StatefulWidget {
      final String url;
    
      const AgeCharts({this.url});
    
      @override
      _AgeChartsState createState() => _AgeChartsState();
    }
    
    class _AgeChartsState extends State<AgeCharts> {
      var chart;
    
      Future<List<Ages>> getChartData(widget) async {
        final response = await http.get(widget.url);
        final List<dynamic> jsonData = jsonDecode(response.body)['data'];
        return jsonData.map((data) => Ages.fromJson(data)).toList();
      }
    
      @override
      Widget build(BuildContext context) {
        return SafeArea(
          child: Scaffold(
            appBar: AppBar(
              title: Text('Japanese Age Working Populations'),
            ),
            body: Padding(
              padding: EdgeInsets.all(8.0),
              child: FutureBuilder<List>(
                future: getChartData(widget),
                builder: (context, dataapi) {
                  if (dataapi.hasError) print(dataapi.error);
                  return dataapi.hasData
                      ? ShowChart(data: dataapi.data)
                      : Center(child: CircularProgressIndicator());
                },
              ),
            ),
          ),
        );
      }
    }
    
    // CHART
    
    class ShowChart extends StatelessWidget {
      final List<Ages> data;
    
      ShowChart({this.data});
    
      static List<charts.Series<Ages, num>> _createSampleData(dataAPI) {
        return [
          new charts.Series<Ages, num>(
            id: 'underAge15',
            colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault,
            areaColorFn: (_, __) =>
                charts.MaterialPalette.blue.shadeDefault.lighter,
            domainFn: (Ages ages, _) => ages.year,
            measureFn: (Ages ages, _) => double.parse(ages.underAge15).round(),
            data: dataAPI,
          ),
          new charts.Series<Ages, num>(
            id: 'age1564',
            colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault,
            areaColorFn: (_, __) => charts.MaterialPalette.red.shadeDefault.lighter,
            domainFn: (Ages ages, _) => ages.year,
            measureFn: (Ages ages, _) => double.parse(ages.age1564).round(),
            data: dataAPI,
          ),
          new charts.Series<Ages, num>(
            id: 'age65Over',
            colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault,
            areaColorFn: (_, __) =>
                charts.MaterialPalette.green.shadeDefault.lighter,
            domainFn: (Ages ages, _) => ages.year,
            measureFn: (Ages ages, _) => double.parse(ages.age65Over).round(),
            data: dataAPI,
          ),
        ];
      }
    
      @override
      Widget build(BuildContext context) {
        return Container(
          child: charts.LineChart(
            _createSampleData(data),
            defaultRenderer:
                new charts.LineRendererConfig(includeArea: true, stacked: true),
            animate: true,
            domainAxis: charts.NumericAxisSpec(
              tickProviderSpec:
                  charts.BasicNumericTickProviderSpec(zeroBound: false),
            ),
          ),
        );
      }
    }
    
    // DOMAIN
    
    class Ages {
      Ages({
        this.entity,
        this.code,
        this.year,
        this.underAge15,
        this.age1564,
        this.age65Over,
      });
    
      String entity;
      String code;
      int year;
      String underAge15;
      String age1564;
      String age65Over;
    
      factory Ages.fromJson(Map<String, dynamic> json) => Ages(
            entity: json["entity"],
            code: json["code"],
            year: json["year"],
            underAge15: json["under_age_15"],
            age1564: json["age_15_64"],
            age65Over: json["age_65_over"],
          );
    
      Map<String, dynamic> toJson() => {
            "entity": entity,
            "code": code,
            "year": year,
            "under_age_15": underAge15,
            "age_15_64": age1564,
            "age_65_over": age65Over,
          };
    }
    
    // DATA
    
    math.Random random = math.Random();
    
    final Map<String, dynamic> data = {
      "status": true,
      "message": "Chart found",
      "data": List.generate(
          20,
          (index) => {
                "entity": "Japan",
                "code": "JPN",
                "year": 1950 + index,
                "under_age_15": (25000 + random.nextInt(5000)).toString(),
                "age_15_64": (40000 + random.nextInt(5000)).toString(),
                "age_65_over": (3000 + random.nextInt(2000)).toString(),
              }).toList(),
    };
    
    Future<List<Ages>> getChartData(widget) async {
      final response = await http.get(widget.url);
      return json.decode(response.body)['data'].map((jsonData) => Ages.fromJson(jsonData)).toList();
    }