I am trying to implement my API data in a chart using fl_chart dependencies in flutter. But I just cannot figure out how to implement it.
Here is how I implement my data:
@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),
strokeWidth: 1,
);
},
),
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),
fontWeight: FontWeight.bold,
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, 4),
],
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(),
),
),
],
)
And here is how i call my data:
Map<String, List<TankPing>> pings;
initState() {
Services.fetchPing().then((tankPings) => {
setState((){
pings = tankPings;
})
});
super.initState();
}
My API call is in another file. I call the API like below:
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');
}
}
I am trying to implement it inside of FlSPot() function. But then U receive this error:
The method '[]' was called on null.
Receiver: null
Tried calling: []("1")
Here is my model:
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, v) => MapEntry<String, 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,
};
}
Here is how the API look:
{
"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
},
]
My API is very long and it looks like that. Any help would be appreciated.
The answer is use the min and max value to determine how long the data will be. And then just use the flSpot to enter your data.