问题描述
我正在尝试使用 Flutter 中的 fl_chart
依赖项在图表中实现我的 API 数据。但我就是不知道如何实现它。
以下是我实现数据的方式:
@override
Widget build(BuildContext context) {
return ListView.builder(
padding: EdgeInsets.zero,shrinkWrap: true,scrollDirection: Axis.vertical,physics: NeverScrollableScrollPhysics(),itemCount: 1,itemBuilder: (context,index){
// ignore: unused_local_variable
int number = index + 1;
return Container(
width: MediaQuery.of(context).size.width * 0.50,child: LineChart(
LineChartData(
gridData: FlGridData(
show: true,drawVerticalLine: true,getDrawingHorizontalLine: (value) {
return FlLine(
color: const Color(0xff37434d),strokeWidth: 1,);
},getDrawingVerticalLine: (value) {
return FlLine(
color: const Color(0xff37434d),),titlesData: FlTitlesData(
show: true,bottomTitles: SideTitles(
showTitles: true,reservedSize: 22,getTextStyles: (value) =>
const TextStyle(color: Color(0xff68737d),fontWeight: FontWeight.bold,fontSize: 16),getTitles: (value) {
switch (value.toInt()) {
case 2:
return 'MAR';
case 5:
return 'JUN';
case 8:
return 'SEP';
}
return '';
},margin: 8,leftTitles: SideTitles(
showTitles: true,getTextStyles: (value) => const TextStyle(
color: Color(0xff67727d),fontSize: 15,getTitles: (value) {
switch (value.toInt()) {
case 1:
return '10k';
case 3:
return '30k';
case 5:
return '50k';
}
return '';
},reservedSize: 28,margin: 12,borderData:
FlBorderData(show: true,border: Border.all(color: const Color(0xff37434d),width: 1)),minX: 0,maxX: 11,minY: 0,maxY: 6,lineBarsData: [
LineChartBarData(
spots: [
FlSpot(0,pings[number.toString()][index].volume),FlSpot(2.6,2),FlSpot(4.9,5),FlSpot(6.8,3.1),FlSpot(8,4),FlSpot(9.5,3),FlSpot(11,],isCurved: true,colors: gradientColors,barWidth: 5,isstrokeCapRound: true,dotData: FlDotData(
show: true,belowBarData: BarareaData(
show: true,colors: gradientColors.map((color) => color.withOpacity(0.3)).toList(),)
这是我如何调用我的数据:
Map<String,List<TankPing>> pings;
initState() {
Services.fetchPing().then((tankPings) => {
setState((){
pings = tankPings;
})
});
super.initState();
}
static Future<Map<String,List<TankPing>>> fetchPing() async {
String url3 = 'https://api.orbital.katsana.com/devices/graph-data';
Future<SharedPreferences> _prefs = SharedPreferences.getInstance();
final SharedPreferences prefs = await _prefs;
final token = prefs.getString('access_token');
final response3 = await http.get(url3,headers: {
'Authorization': 'Bearer $token'
});
if(response3.statusCode == 200) {
final tankPings = tankPingFromJson(response3.body);
return tankPings;
}else if(response3.statusCode == 400) {
print('Connection to server is bad');
}else if(response3.statusCode == 500){
print('No authorization');
}
}
我正在尝试在 FlSPot()
函数中实现它。但是后来你收到这个错误:
The method '[]' was called on null.
Receiver: null
Tried calling: []("1")
这是我的模型:
import 'dart:convert';
Map<String,List<TankPing>> tankPingFromJson(dynamic str) => Map.from(json.decode(str)).map((k,v) => MapEntry<String,List<TankPing>>(k,List<TankPing>.from(v.map((x) => TankPing.fromJson(x)))));
String tankPingToJson(Map<String,List<TankPing>> data) => json.encode(Map.from(data).map((k,dynamic>(k,List<dynamic>.from(v.map((x) => x.toJson())))));
class TankPing {
TankPing({
this.trackedAt,this.fuel,this.level,this.volume,});
DateTime trackedAt;
double fuel;
double level;
double volume;
factory TankPing.fromJson(Map<String,dynamic> json) => TankPing(
trackedAt: DateTime.parse(json["tracked_at"]),fuel: json["fuel"].todouble(),level: json["level"].todouble(),volume: json["volume"].todouble(),);
Map<String,dynamic> toJson() => {
"tracked_at": trackedAt.toString(),"fuel": fuel,"level": level,"volume": volume,};
}
API 的外观如下:
{
"1": [
{
"tracked_at": "2020-11-20T19:41:21.000000Z","fuel": 87.03,"level": 3.0460554,"volume": 50665.14
},{
"tracked_at": "2020-11-22T00:19:41.000000Z","fuel": 85.75,"level": 3.0012249,"volume": 50051.86
},{
"tracked_at": "2020-11-22T00:32:00.000000Z","fuel": 84.17,"level": 2.9460489,"volume": 49265.04
},]
我的 API 很长,看起来就是这样。任何帮助将不胜感激。
解决方法
答案是使用最小值和最大值来确定数据的长度。然后只需使用 flSpot 输入您的数据。