Create flutter chart with json api data

I’m creating a flutter app to receive data from the Yahoo finance API and show this data in a chart widget. This is my detail page, getting the “Symbol”-Information from the homepage. That’s working fine, the URI too (eg https://query1.finance.yahoo.com/v7/finance/chart/ADS.DE?range=1mo&interval=1d&indicators=quote&includeTimestamp=true) I get the JSON data.

import 'package:flutter/material.dart';
import 'package:stock_list_app/app/models/yahoo_chart.dart';
import 'package:stock_list_app/app/services/api_yahoo_chart.dart';

class DetailPage extends StatefulWidget {
  @override
  _DetailPageState createState() => _DetailPageState();
}

class _DetailPageState extends State<DetailPage> {
  late Future<Chart> _chartModel;
  var _symbol;

  @override
  void initState() {
    super.initState();
  }

  @override
  void didChangeDependencies() {
    _symbol = ModalRoute.of(context)?.settings.arguments;
    _chartModel = APIServiceYahoo().getChart(_symbol.toString());
  }

  @override
  Widget build(BuildContext context) {
    final from = ModalRoute.of(context)?.settings.arguments;

    return Scaffold(
        body: Center(
      child: FutureBuilder<Chart>(
          future: _chartModel,
          builder: (context, AsyncSnapshot<Chart> snapshot) {
            if (snapshot.hasData) {
              return ListView.separated(
                separatorBuilder: (context, index) {
                  return Divider(color: Colors.grey[400]);
                },
                itemCount: snapshot.data!.chart.result.length,
                itemBuilder: (context, index) {
                  var result = snapshot.data!.chart.result[index];
                  
                  return Row(
                    mainAxisAlignment: MainAxisAlignment.center,
                    children: <Widget>[
                      Column(
                        children: <Widget>[
                          Text(result.timestamp.first.toString()),
                          ElevatedButton(
                            onPressed: () {
                              if (Navigator.of(context).canPop()) {
                                Navigator.of(context)
                                    .pop('Detailspage');
                              }
                            },
                            child: Text('Back'),
                          ),
                        ],
                      ),
                    ],
                  );
                },
              );
            } else
              return Center(child: CircularProgressIndicator());
          }),
    ));
  }
}

With var result I can access the class to get the data from the JSON string. As you can see by showing the last timestamp value. But only down to result.indicators. I have no access to eg result.indicators.quote.close.

And the next issue, I have no clue how to put result.timestamp and result.indicators.quote.close into a flutter_chart.

And here is my model:


// To parse this JSON data, do
//
//     final chart = chartFromJson(jsonString);

import 'dart:convert';

Chart chartFromJson(String str) => Chart.fromJson(json.decode(str));

String chartToJson(Chart data) => json.encode(data.toJson());

class Chart {
  Chart({
    required this.chart,
  });

  ChartClass chart;

  factory Chart.fromJson(Map<String, dynamic> json) => Chart(
        chart: ChartClass.fromJson(json["chart"]),
      );

  Map<String, dynamic> toJson() => {
        "chart": chart.toJson(),
      };
}

class ChartClass {
  ChartClass({
    required this.result,
    required this.error,
  });

  List<Result> result;
  dynamic error;

  factory ChartClass.fromJson(Map<String, dynamic> json) => ChartClass(
        result:
            List<Result>.from(json["result"].map((x) => Result.fromJson(x))),
        error: json["error"],
      );

  Map<String, dynamic> toJson() => {
        "result": List<dynamic>.from(result.map((x) => x.toJson())),
        "error": error,
      };
}

class Datum {
  Datum({
    required this.date,
    required this.close,
  });

  final DateTime date;
  final double close;

  Datum.fromJson(Map<String, dynamic> json)
      : date = DateTime.parse(json['timestamp']),
        close = json['close'].toDouble();
}

class Result {
  Result({
    required this.meta,
    required this.timestamp,
    required this.indicators,
  });

  DateTime formatTimestamp(int timestamp) {
    var date = DateTime.fromMicrosecondsSinceEpoch(timestamp * 1000);
    return date;
  }

  Meta meta;
  List<DateTime> timestamp;
  Indicators indicators;

  factory Result.fromJson(Map<String, dynamic> json) => Result(
        meta: Meta.fromJson(json["meta"]),
        timestamp: List<DateTime>.from(json["timestamp"]
            .map((x) => DateTime.fromMillisecondsSinceEpoch(x * 1000))),
        indicators: Indicators.fromJson(json["indicators"]),
      );

  Map<String, dynamic> toJson() => {
        "meta": meta.toJson(),
        "timestamp": List<dynamic>.from(timestamp.map((x) => x)),
        "indicators": indicators.toJson(),
      };
}

class Indicators {
  Indicators({
    required this.quote,
    required this.adjclose,
  });

  List<Quote> quote;
  List<Adjclose> adjclose;

  factory Indicators.fromJson(Map<String, dynamic> json) => Indicators(
        quote: List<Quote>.from(json["quote"].map((x) => Quote.fromJson(x))),
        adjclose: List<Adjclose>.from(
            json["adjclose"].map((x) => Adjclose.fromJson(x))),
      );

  Map<String, dynamic> toJson() => {
        "quote": List<dynamic>.from(quote.map((x) => x.toJson())),
        "adjclose": List<dynamic>.from(adjclose.map((x) => x.toJson())),
      };
}

class Adjclose {
  Adjclose({
    required this.adjclose,
  });

  List<double> adjclose;

  factory Adjclose.fromJson(Map<String, dynamic> json) => Adjclose(
        adjclose: List<double>.from(json["adjclose"].map((x) => x.toDouble())),
      );

  Map<String, dynamic> toJson() => {
        "adjclose": List<dynamic>.from(adjclose.map((x) => x)),
      };
}

class Quote {
  Quote({
    required this.high,
    required this.close,
    required this.low,
    required this.volume,
    required this.open,
  });

  List<double> high;
  List<double> close;
  List<double> low;
  List<int> volume;
  List<double> open;

  factory Quote.fromJson(Map<String, dynamic> json) => Quote(
        high: List<double>.from(json["high"].map((x) => x.toDouble())),
        close: List<double>.from(json["close"].map((x) => x.toDouble())),
        low: List<double>.from(json["low"].map((x) => x.toDouble())),
        volume: List<int>.from(json["volume"].map((x) => x)),
        open: List<double>.from(json["open"].map((x) => x.toDouble())),
      );

  Map<String, dynamic> toJson() => {
        "high": List<dynamic>.from(high.map((x) => x)),
        "close": List<dynamic>.from(close.map((x) => x)),
        "low": List<dynamic>.from(low.map((x) => x)),
        "volume": List<dynamic>.from(volume.map((x) => x)),
        "open": List<dynamic>.from(open.map((x) => x)),
      };
}

class Meta {
  Meta({
    required this.currency,
    required this.symbol,
    required this.exchangeName,
    required this.instrumentType,
    required this.firstTradeDate,
    required this.regularMarketTime,
    required this.gmtoffset,
    required this.timezone,
    required this.exchangeTimezoneName,
    required this.regularMarketPrice,
    required this.chartPreviousClose,
    required this.priceHint,
    required this.currentTradingPeriod,
    required this.dataGranularity,
    required this.range,
    required this.validRanges,
  });

  String currency;
  String symbol;
  String exchangeName;
  String instrumentType;
  int firstTradeDate;
  int regularMarketTime;
  int gmtoffset;
  String timezone;
  String exchangeTimezoneName;
  double regularMarketPrice;
  double chartPreviousClose;
  int priceHint;
  CurrentTradingPeriod currentTradingPeriod;
  String dataGranularity;
  String range;
  List<String> validRanges;

  factory Meta.fromJson(Map<String, dynamic> json) => Meta(
        currency: json["currency"],
        symbol: json["symbol"],
        exchangeName: json["exchangeName"],
        instrumentType: json["instrumentType"],
        firstTradeDate: json["firstTradeDate"],
        regularMarketTime: json["regularMarketTime"],
        gmtoffset: json["gmtoffset"],
        timezone: json["timezone"],
        exchangeTimezoneName: json["exchangeTimezoneName"],
        regularMarketPrice: json["regularMarketPrice"].toDouble(),
        chartPreviousClose: json["chartPreviousClose"].toDouble(),
        priceHint: json["priceHint"],
        currentTradingPeriod:
            CurrentTradingPeriod.fromJson(json["currentTradingPeriod"]),
        dataGranularity: json["dataGranularity"],
        range: json["range"],
        validRanges: List<String>.from(json["validRanges"].map((x) => x)),
      );

  Map<String, dynamic> toJson() => {
        "currency": currency,
        "symbol": symbol,
        "exchangeName": exchangeName,
        "instrumentType": instrumentType,
        "firstTradeDate": firstTradeDate,
        "regularMarketTime": regularMarketTime,
        "gmtoffset": gmtoffset,
        "timezone": timezone,
        "exchangeTimezoneName": exchangeTimezoneName,
        "regularMarketPrice": regularMarketPrice,
        "chartPreviousClose": chartPreviousClose,
        "priceHint": priceHint,
        "currentTradingPeriod": currentTradingPeriod.toJson(),
        "dataGranularity": dataGranularity,
        "range": range,
        "validRanges": List<dynamic>.from(validRanges.map((x) => x)),
      };
}

class CurrentTradingPeriod {
  CurrentTradingPeriod({
    required this.pre,
    required this.regular,
    required this.post,
  });

  Post pre;
  Post regular;
  Post post;

  factory CurrentTradingPeriod.fromJson(Map<String, dynamic> json) =>
      CurrentTradingPeriod(
        pre: Post.fromJson(json["pre"]),
        regular: Post.fromJson(json["regular"]),
        post: Post.fromJson(json["post"]),
      );

  Map<String, dynamic> toJson() => {
        "pre": pre.toJson(),
        "regular": regular.toJson(),
        "post": post.toJson(),
      };
}

class Post {
  Post({
    required this.timezone,
    required this.start,
    required this.end,
    required this.gmtoffset,
  });

  String timezone;
  int start;
  int end;
  int gmtoffset;

  factory Post.fromJson(Map<String, dynamic> json) => Post(
        timezone: json["timezone"],
        start: json["start"],
        end: json["end"],
        gmtoffset: json["gmtoffset"],
      );

  Map<String, dynamic> toJson() => {
        "timezone": timezone,
        "start": start,
        "end": end,
        "gmtoffset": gmtoffset,
      };
}

class TimeSeriesPrice {
  TimeSeriesPrice({
    required this.timestamp,
    required this.indicators,
  });

  final DateTime timestamp;
  final double indicators;

  factory TimeSeriesPrice.fromJson(Map<String, dynamic> json) =>
      TimeSeriesPrice(
        timestamp: json["timestamp"]
            .map((x) => DateTime.fromMillisecondsSinceEpoch(x * 1000)),
        indicators: json["indicators"].todouble(),
      );

  Map<String, dynamic> toJson() => {
        "timestamp": timestamp,
        "indicators": indicators,
      };
}

Any idea what’s the next step? Thanks

Leave a Comment