add structure
This commit is contained in:
107
lib/charts/lines.dart
Normal file
107
lib/charts/lines.dart
Normal file
@@ -0,0 +1,107 @@
|
||||
import 'package:charts_flutter/flutter.dart' as charts;
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:intl/intl.dart';
|
||||
|
||||
import '../model/product_model.dart';
|
||||
|
||||
typedef void ProductClick(DateTime date, Map<String, int> measures);
|
||||
|
||||
class ProductsChart extends StatelessWidget {
|
||||
static final numberFormatter = new NumberFormat("#,###");
|
||||
final ChartData chartData;
|
||||
final ProductClick productClick;
|
||||
const ProductsChart(this.chartData, {Key key, this.productClick})
|
||||
: super(key: key);
|
||||
factory ProductsChart.fromModel(ProductModel productModel,
|
||||
{ProductClick productClick}) {
|
||||
return new ProductsChart(_createData(productModel),
|
||||
productClick: productClick);
|
||||
}
|
||||
|
||||
static ChartData _createData(ProductModel productModel) {
|
||||
List<charts.Series<TimeSeriesSales, DateTime>> list = [];
|
||||
var min = 9999, max = 0;
|
||||
productModel.products.forEach((p) {
|
||||
List<TimeSeriesSales> data = [];
|
||||
if (p.priceHistory != null) {
|
||||
var dateKeys = {};
|
||||
p.priceHistory.entries.forEach((e) {
|
||||
dateKeys[DateTime.parse(e.key)] = e.value;
|
||||
});
|
||||
|
||||
var sortedKeys = dateKeys.keys.toList()..sort((a, b) => b.compareTo(a));
|
||||
sortedKeys.forEach((k) {
|
||||
var v = dateKeys[k];
|
||||
data.add(new TimeSeriesSales(k, v));
|
||||
if (v < min) min = v;
|
||||
if (v > max) max = v;
|
||||
});
|
||||
}
|
||||
|
||||
list.add(new charts.Series<TimeSeriesSales, DateTime>(
|
||||
id: p.name,
|
||||
colorFn: (_, __) => charts.ColorUtil.fromDartColor(Color(p.color)),
|
||||
domainFn: (TimeSeriesSales sales, _) => sales.time,
|
||||
measureFn: (TimeSeriesSales sales, _) => sales.sales,
|
||||
data: data,
|
||||
labelAccessorFn: (TimeSeriesSales series, _) =>
|
||||
'${numberFormatter.format(series.sales)}',
|
||||
measureFormatterFn: (TimeSeriesSales series, _) => (n) => "s",
|
||||
));
|
||||
});
|
||||
var chartData = ChartData(list, min, max);
|
||||
return chartData;
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return charts.TimeSeriesChart(
|
||||
chartData.seriesList,
|
||||
animate: true,
|
||||
defaultRenderer: new charts.LineRendererConfig(
|
||||
includePoints: true,
|
||||
),
|
||||
primaryMeasureAxis: new charts.NumericAxisSpec(
|
||||
tickProviderSpec: new charts.BasicNumericTickProviderSpec(
|
||||
zeroBound: false, desiredTickCount: 10),
|
||||
renderSpec: new charts.GridlineRendererSpec(
|
||||
lineStyle: charts.LineStyleSpec(
|
||||
dashPattern: [4, 4],
|
||||
))),
|
||||
selectionModels: [
|
||||
new charts.SelectionModelConfig(
|
||||
type: charts.SelectionModelType.info,
|
||||
updatedListener: _onSelectionChanged,
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
_onSelectionChanged(charts.SelectionModel model) {
|
||||
final selectedDatum = model.selectedDatum;
|
||||
if (selectedDatum.isNotEmpty) {
|
||||
var _time = selectedDatum.first.datum.time;
|
||||
Map<String, int> _measures = <String, int>{};
|
||||
|
||||
selectedDatum.forEach((charts.SeriesDatum datumPair) {
|
||||
_measures[datumPair.series.displayName] = datumPair.datum.sales;
|
||||
});
|
||||
if (productClick != null) {
|
||||
productClick(_time, _measures);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
class TimeSeriesSales {
|
||||
final DateTime time;
|
||||
final int sales;
|
||||
|
||||
TimeSeriesSales(this.time, this.sales);
|
||||
}
|
||||
|
||||
class ChartData {
|
||||
final List<charts.Series> seriesList;
|
||||
final num min, max;
|
||||
ChartData(this.seriesList, this.min, this.max);
|
||||
}
|
||||
Reference in New Issue
Block a user