| // Copyright 2014 The Flutter Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| // Snapshot from http://www.nasdaq.com/screening/company-list.aspx |
| // Fetched 2/23/2014. |
| // "Symbol","Name","LastSale","MarketCap","IPOyear","Sector","industry","Summary Quote", |
| // Data in stock_data.json |
| |
| import 'dart:convert'; |
| import 'dart:math' as math; |
| |
| import 'package:flutter/foundation.dart'; |
| import 'package:http/http.dart' as http; |
| |
| final math.Random _rng = math.Random(); |
| |
| class Stock { |
| Stock(this.symbol, this.name, this.lastSale, this.marketCap, this.percentChange); |
| |
| Stock.fromFields(List<String> fields) { |
| // TODO(jackson): This class should only have static data, not lastSale, etc. |
| // "Symbol","Name","LastSale","MarketCap","IPOyear","Sector","industry","Summary Quote", |
| lastSale = 0.0; |
| try { |
| lastSale = double.parse(fields[2]); |
| } catch (_) { } |
| symbol = fields[0]; |
| name = fields[1]; |
| marketCap = fields[4]; |
| percentChange = (_rng.nextDouble() * 20) - 10; |
| } |
| |
| String symbol; |
| String name; |
| double lastSale; |
| String marketCap; |
| double percentChange; |
| } |
| |
| class StockData extends ChangeNotifier { |
| StockData() { |
| if (actuallyFetchData) { |
| _httpClient = http.Client(); |
| _fetchNextChunk(); |
| } |
| } |
| |
| final List<String> _symbols = <String>[]; |
| final Map<String, Stock> _stocks = <String, Stock>{}; |
| |
| List<String> get allSymbols => _symbols; |
| |
| Stock operator [](String symbol) => _stocks[symbol]; |
| |
| bool get loading => _httpClient != null; |
| |
| void add(List<dynamic> data) { |
| for (final List<dynamic> fields in data.cast<List<dynamic>>()) { |
| final Stock stock = Stock.fromFields(fields.cast<String>()); |
| _symbols.add(stock.symbol); |
| _stocks[stock.symbol] = stock; |
| } |
| _symbols.sort(); |
| notifyListeners(); |
| } |
| |
| static const int _chunkCount = 30; |
| int _nextChunk = 0; |
| |
| String _urlToFetch(int chunk) { |
| return 'https://domokit.github.io/examples/stocks/data/stock_data_$chunk.json'; |
| } |
| |
| http.Client _httpClient; |
| |
| static bool actuallyFetchData = true; |
| |
| void _fetchNextChunk() { |
| _httpClient.get(_urlToFetch(_nextChunk++)).then<void>((http.Response response) { |
| final String json = response.body; |
| if (json == null) { |
| debugPrint('Failed to load stock data chunk ${_nextChunk - 1}'); |
| _end(); |
| return; |
| } |
| const JsonDecoder decoder = JsonDecoder(); |
| add(decoder.convert(json) as List<dynamic>); |
| if (_nextChunk < _chunkCount) { |
| _fetchNextChunk(); |
| } else { |
| _end(); |
| } |
| }); |
| } |
| |
| void _end() { |
| _httpClient?.close(); |
| _httpClient = null; |
| } |
| } |