Flutter 颤振-将API用于带模型的图表
这个问题我已经解决了将近三天了。已经在另一个问题中发布了,但得到的答案是负数。 让我把问题说清楚。 我想将使用模型的api数据放入chart Flatter,这是我的代码 首先是我的模特儿这里是我的年龄模特儿 年龄.飞镖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());
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();
}