如何在折线图中实现 API 数据

问题描述

我正在尝试使用 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();
  }

我的 API 调用在另一个文件中。我调用 API 如下:

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 输入您的数据。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...