From 4ab078c45e19f58d0375c99ed185668aed464764 Mon Sep 17 00:00:00 2001 From: Felix Date: Wed, 17 Jul 2019 12:31:28 +0100 Subject: [PATCH] Statistics/graphs section implemented Only using sample data atm --- ios/Podfile.lock | 4 +- ios/Runner.xcodeproj/project.pbxproj | 2 +- lib/common/widgets/charts/auto_label.dart | 74 ++++++++ lib/common/widgets/charts/donut_chart.dart | 56 ++++++ .../widgets/charts/grouped_bar_chart.dart | 81 ++++++++ .../charts/numeric_line_bar_combo.dart | 95 ++++++++++ lib/common/widgets/charts/outside_label.dart | 69 +++++++ .../charts/scatter_bucketingAxis_legend.dart | 136 ++++++++++++++ .../charts/series_legend_with_measures.dart | 129 +++++++++++++ lib/pages/receipt_page.dart | 2 +- lib/pages/stats_page.dart | 175 +++++++++++++++++- pubspec.lock | 14 ++ pubspec.yaml | 2 +- 13 files changed, 829 insertions(+), 10 deletions(-) create mode 100644 lib/common/widgets/charts/auto_label.dart create mode 100644 lib/common/widgets/charts/donut_chart.dart create mode 100644 lib/common/widgets/charts/grouped_bar_chart.dart create mode 100644 lib/common/widgets/charts/numeric_line_bar_combo.dart create mode 100644 lib/common/widgets/charts/outside_label.dart create mode 100644 lib/common/widgets/charts/scatter_bucketingAxis_legend.dart create mode 100644 lib/common/widgets/charts/series_legend_with_measures.dart diff --git a/ios/Podfile.lock b/ios/Podfile.lock index f5bffe1..81f2036 100644 --- a/ios/Podfile.lock +++ b/ios/Podfile.lock @@ -6,13 +6,13 @@ PODS: - Flutter DEPENDENCIES: - - Flutter (from `.symlinks/flutter/ios`) + - Flutter (from `.symlinks/flutter/ios-profile`) - shared_preferences (from `.symlinks/plugins/shared_preferences/ios`) - url_launcher (from `.symlinks/plugins/url_launcher/ios`) EXTERNAL SOURCES: Flutter: - :path: ".symlinks/flutter/ios" + :path: ".symlinks/flutter/ios-profile" shared_preferences: :path: ".symlinks/plugins/shared_preferences/ios" url_launcher: diff --git a/ios/Runner.xcodeproj/project.pbxproj b/ios/Runner.xcodeproj/project.pbxproj index a83a4d3..dff0209 100644 --- a/ios/Runner.xcodeproj/project.pbxproj +++ b/ios/Runner.xcodeproj/project.pbxproj @@ -281,7 +281,7 @@ ); inputPaths = ( "${PODS_ROOT}/Target Support Files/Pods-Runner/Pods-Runner-frameworks.sh", - "${PODS_ROOT}/../.symlinks/flutter/ios/Flutter.framework", + "${PODS_ROOT}/../.symlinks/flutter/ios-profile/Flutter.framework", ); name = "[CP] Embed Pods Frameworks"; outputPaths = ( diff --git a/lib/common/widgets/charts/auto_label.dart b/lib/common/widgets/charts/auto_label.dart new file mode 100644 index 0000000..96f7209 --- /dev/null +++ b/lib/common/widgets/charts/auto_label.dart @@ -0,0 +1,74 @@ +/// Donut chart with labels example. This is a simple pie chart with a hole in +/// the middle. +import 'package:charts_flutter/flutter.dart' as charts; +import 'package:flutter/material.dart'; + +class DonutAutoLabelChart extends StatelessWidget { + final List seriesList; + final bool animate; + + DonutAutoLabelChart(this.seriesList, {this.animate}); + + /// Creates a [PieChart] with sample data and no transition. + factory DonutAutoLabelChart.withSampleData() { + return new DonutAutoLabelChart( + _createSampleData(), + // Disable animations for image tests. + animate: true, + ); + } + + + @override + Widget build(BuildContext context) { + return new charts.PieChart(seriesList, + animate: animate, + // Configure the width of the pie slices to 60px. The remaining space in + // the chart will be left as a hole in the center. + // + // [ArcLabelDecorator] will automatically position the label inside the + // arc if the label will fit. If the label will not fit, it will draw + // outside of the arc with a leader line. Labels can always display + // inside or outside using [LabelPosition]. + // + // Text style for inside / outside can be controlled independently by + // setting [insideLabelStyleSpec] and [outsideLabelStyleSpec]. + // + // Example configuring different styles for inside/outside: + // new charts.ArcLabelDecorator( + // insideLabelStyleSpec: new charts.TextStyleSpec(...), + // outsideLabelStyleSpec: new charts.TextStyleSpec(...)), + defaultRenderer: new charts.ArcRendererConfig( + arcWidth: 60, + arcRendererDecorators: [new charts.ArcLabelDecorator()])); + } + + /// Create one series with sample hard coded data. + static List> _createSampleData() { + final data = [ + new LinearSales("Other", 17), + new LinearSales("Mars", 26), + new LinearSales("Morecambe", 35), + new LinearSales("Lancaster", 48), + ]; + + return [ + new charts.Series( + id: 'Sales', + domainFn: (LinearSales sales, _) => sales.key, + measureFn: (LinearSales sales, _) => sales.sales, + data: data, + // Set a label accessor to control the text of the arc label. + labelAccessorFn: (LinearSales row, _) => '${row.key}: ${row.sales}', + ) + ]; + } +} + +/// Sample linear data type. +class LinearSales { + final String key; + final int sales; + + LinearSales(this.key, this.sales); +} \ No newline at end of file diff --git a/lib/common/widgets/charts/donut_chart.dart b/lib/common/widgets/charts/donut_chart.dart new file mode 100644 index 0000000..06feda5 --- /dev/null +++ b/lib/common/widgets/charts/donut_chart.dart @@ -0,0 +1,56 @@ +/// Donut chart example. This is a simple pie chart with a hole in the middle. +import 'package:charts_flutter/flutter.dart' as charts; +import 'package:flutter/material.dart'; + +class DonutPieChart extends StatelessWidget { + final List seriesList; + final bool animate; + + DonutPieChart(this.seriesList, {this.animate}); + + /// Creates a [PieChart] with sample data and no transition. + factory DonutPieChart.withSampleData() { + return new DonutPieChart( + _createSampleData(), + animate: true, + ); + } + + + @override + Widget build(BuildContext context) { + return new charts.PieChart(seriesList, + animate: animate, + // Configure the width of the pie slices to 60px. The remaining space in + // the chart will be left as a hole in the center. + defaultRenderer: new charts.ArcRendererConfig(arcWidth: 60)); + } + + /// Create one series with sample hard coded data. + static List> _createSampleData() { + final data = [ + new LinearSales(0, 100), + new LinearSales(1, 75), + new LinearSales(2, 25), + new LinearSales(3, 5), + ]; + + return [ + new charts.Series( + id: 'Sales', + domainFn: (LinearSales sales, _) => sales.year, + measureFn: (LinearSales sales, _) => sales.sales, + data: data, + ) + ]; + } +} + + +/// Sample linear data type. +class LinearSales { + final int year; + final int sales; + + LinearSales(this.year, this.sales); +} \ No newline at end of file diff --git a/lib/common/widgets/charts/grouped_bar_chart.dart b/lib/common/widgets/charts/grouped_bar_chart.dart new file mode 100644 index 0000000..24554e5 --- /dev/null +++ b/lib/common/widgets/charts/grouped_bar_chart.dart @@ -0,0 +1,81 @@ +/// Bar chart example +import 'package:flutter/material.dart'; +import 'package:charts_flutter/flutter.dart' as charts; + +class GroupedBarChart extends StatelessWidget { + final List seriesList; + final bool animate; + + GroupedBarChart(this.seriesList, {this.animate}); + + factory GroupedBarChart.withSampleData() { + return new GroupedBarChart( + _createSampleData(), + // Disable animations for image tests. + animate: false, + ); + } + + + @override + Widget build(BuildContext context) { + return new charts.BarChart( + seriesList, + animate: animate, + barGroupingType: charts.BarGroupingType.grouped, + ); + } + + /// Create series list with multiple series + static List> _createSampleData() { + final desktopSalesData = [ + new OrdinalSales('2014', 5), + new OrdinalSales('2015', 25), + new OrdinalSales('2016', 100), + new OrdinalSales('2017', 75), + ]; + + final tabletSalesData = [ + new OrdinalSales('2014', 25), + new OrdinalSales('2015', 50), + new OrdinalSales('2016', 10), + new OrdinalSales('2017', 20), + ]; + + final mobileSalesData = [ + new OrdinalSales('2014', 10), + new OrdinalSales('2015', 15), + new OrdinalSales('2016', 50), + new OrdinalSales('2017', 45), + ]; + + return [ + new charts.Series( + id: 'Desktop', + domainFn: (OrdinalSales sales, _) => sales.year, + measureFn: (OrdinalSales sales, _) => sales.sales, + data: desktopSalesData, + ), + new charts.Series( + id: 'Tablet', + domainFn: (OrdinalSales sales, _) => sales.year, + measureFn: (OrdinalSales sales, _) => sales.sales, + data: tabletSalesData, + ), + new charts.Series( + id: 'Mobile', + domainFn: (OrdinalSales sales, _) => sales.year, + measureFn: (OrdinalSales sales, _) => sales.sales, + data: mobileSalesData, + ), + ]; + } +} + +/// Sample ordinal data type. +class OrdinalSales { + final String year; + final int sales; + + OrdinalSales(this.year, this.sales); +} \ No newline at end of file diff --git a/lib/common/widgets/charts/numeric_line_bar_combo.dart b/lib/common/widgets/charts/numeric_line_bar_combo.dart new file mode 100644 index 0000000..2f261dd --- /dev/null +++ b/lib/common/widgets/charts/numeric_line_bar_combo.dart @@ -0,0 +1,95 @@ +/// Example of a numeric combo chart with two series rendered as bars, and a +/// third rendered as a line. +import 'package:charts_flutter/flutter.dart' as charts; +import 'package:flutter/material.dart'; + +class NumericComboLineBarChart extends StatelessWidget { + final List seriesList; + final bool animate; + + NumericComboLineBarChart(this.seriesList, {this.animate}); + + /// Creates a [LineChart] with sample data and no transition. + factory NumericComboLineBarChart.withSampleData() { + return new NumericComboLineBarChart( + _createSampleData(), + // Disable animations for image tests. + animate: false, + ); + } + + + @override + Widget build(BuildContext context) { + return new charts.NumericComboChart(seriesList, + animate: animate, + // Configure the default renderer as a line renderer. This will be used + // for any series that does not define a rendererIdKey. + defaultRenderer: new charts.LineRendererConfig(), + // Custom renderer configuration for the bar series. + customSeriesRenderers: [ + new charts.BarRendererConfig( + // ID used to link series to this renderer. + customRendererId: 'customBar') + ]); + } + + /// Create one series with sample hard coded data. + static List> _createSampleData() { + final desktopSalesData = [ + new LinearSales(0, 5), + new LinearSales(1, 25), + new LinearSales(2, 100), + new LinearSales(3, 75), + ]; + + final tableSalesData = [ + new LinearSales(0, 5), + new LinearSales(1, 25), + new LinearSales(2, 100), + new LinearSales(3, 75), + ]; + + final mobileSalesData = [ + new LinearSales(0, 10), + new LinearSales(1, 50), + new LinearSales(2, 200), + new LinearSales(3, 150), + ]; + + return [ + new charts.Series( + id: 'Desktop', + colorFn: (_, __) => charts.MaterialPalette.blue.shadeDefault, + domainFn: (LinearSales sales, _) => sales.year, + measureFn: (LinearSales sales, _) => sales.sales, + data: desktopSalesData, + ) + // Configure our custom bar renderer for this series. + ..setAttribute(charts.rendererIdKey, 'customBar'), + new charts.Series( + id: 'Tablet', + colorFn: (_, __) => charts.MaterialPalette.red.shadeDefault, + domainFn: (LinearSales sales, _) => sales.year, + measureFn: (LinearSales sales, _) => sales.sales, + data: tableSalesData, + ) + // Configure our custom bar renderer for this series. + ..setAttribute(charts.rendererIdKey, 'customBar'), + new charts.Series( + id: 'Mobile', + colorFn: (_, __) => charts.MaterialPalette.green.shadeDefault, + domainFn: (LinearSales sales, _) => sales.year, + measureFn: (LinearSales sales, _) => sales.sales, + data: mobileSalesData), + ]; + } +} + +/// Sample linear data type. +class LinearSales { + final int year; + final int sales; + + LinearSales(this.year, this.sales); +} \ No newline at end of file diff --git a/lib/common/widgets/charts/outside_label.dart b/lib/common/widgets/charts/outside_label.dart new file mode 100644 index 0000000..ba8bc71 --- /dev/null +++ b/lib/common/widgets/charts/outside_label.dart @@ -0,0 +1,69 @@ +/// Simple pie chart with outside labels example. +import 'package:charts_flutter/flutter.dart' as charts; +import 'package:flutter/material.dart'; + +class PieOutsideLabelChart extends StatelessWidget { + final List seriesList; + final bool animate; + + PieOutsideLabelChart(this.seriesList, {this.animate}); + + /// Creates a [PieChart] with sample data and no transition. + factory PieOutsideLabelChart.withSampleData() { + return new PieOutsideLabelChart( + _createSampleData(), + // Disable animations for image tests. + animate: true, + ); + } + + + @override + Widget build(BuildContext context) { + return new charts.PieChart(seriesList, + animate: animate, + // Add an [ArcLabelDecorator] configured to render labels outside of the + // arc with a leader line. + // + // Text style for inside / outside can be controlled independently by + // setting [insideLabelStyleSpec] and [outsideLabelStyleSpec]. + // + // Example configuring different styles for inside/outside: + // new charts.ArcLabelDecorator( + // insideLabelStyleSpec: new charts.TextStyleSpec(...), + // outsideLabelStyleSpec: new charts.TextStyleSpec(...)), + defaultRenderer: new charts.ArcRendererConfig(arcRendererDecorators: [ + new charts.ArcLabelDecorator( + labelPosition: charts.ArcLabelPosition.outside) + ])); + } + + /// Create one series with sample hard coded data. + static List> _createSampleData() { + final data = [ + new LinearSales(0, 23), + new LinearSales(1, 44), + new LinearSales(2, 25), + new LinearSales(3, 15), + ]; + + return [ + new charts.Series( + id: 'Sales', + domainFn: (LinearSales sales, _) => sales.year, + measureFn: (LinearSales sales, _) => sales.sales, + data: data, + // Set a label accessor to control the text of the arc label. + labelAccessorFn: (LinearSales row, _) => '${row.year}: ${row.sales}', + ) + ]; + } +} + +/// Sample linear data type. +class LinearSales { + final int year; + final int sales; + + LinearSales(this.year, this.sales); +} \ No newline at end of file diff --git a/lib/common/widgets/charts/scatter_bucketingAxis_legend.dart b/lib/common/widgets/charts/scatter_bucketingAxis_legend.dart new file mode 100644 index 0000000..3d7a2ff --- /dev/null +++ b/lib/common/widgets/charts/scatter_bucketingAxis_legend.dart @@ -0,0 +1,136 @@ +/// Example of a scatter plot chart with a bucketing measure axis and a legend. +/// +/// A bucketing measure axis positions all values beneath a certain threshold +/// into a reserved space on the axis range. The label for the bucket line will +/// be drawn in the middle of the bucket range, rather than aligned with the +/// gridline for that value's position on the scale. +import 'package:charts_flutter/flutter.dart' as charts; +import 'package:flutter/material.dart'; + +class BucketingAxisScatterPlotChart extends StatelessWidget { + final List seriesList; + final bool animate; + + BucketingAxisScatterPlotChart(this.seriesList, {this.animate}); + + /// Creates a [ScatterPlotChart] with sample data and no transition. + factory BucketingAxisScatterPlotChart.withSampleData() { + return new BucketingAxisScatterPlotChart( + _createSampleData(), + // Disable animations for image tests. + animate: false, + ); + } + + + @override + Widget build(BuildContext context) { + return new charts.ScatterPlotChart(seriesList, + // Set up a bucketing axis that will place all values below 0.1 (10%) + // into a bucket at the bottom of the chart. + // + // Configure a tick count of 3 so that we get 100%, 50%, and the + // threshold. + primaryMeasureAxis: new charts.BucketingAxisSpec( + threshold: 0.1, + tickProviderSpec: new charts.BucketingNumericTickProviderSpec( + desiredTickCount: 3)), + // Add a series legend to display the series names. + behaviors: [ + new charts.SeriesLegend(position: charts.BehaviorPosition.end), + ], + animate: animate); + } + + /// Create one series with sample hard coded data. + static List> _createSampleData() { + final myFakeDesktopData = [ + new LinearSales(52, 0.75, 14.0), + ]; + + final myFakeTabletData = [ + new LinearSales(45, 0.3, 18.0), + ]; + + final myFakeMobileData = [ + new LinearSales(56, 0.8, 17.0), + ]; + + final myFakeChromebookData = [ + new LinearSales(25, 0.6, 13.0), + ]; + + final myFakeHomeData = [ + new LinearSales(34, 0.5, 15.0), + ]; + + final myFakeOtherData = [ + new LinearSales(10, 0.25, 15.0), + new LinearSales(12, 0.075, 14.0), + new LinearSales(13, 0.225, 15.0), + new LinearSales(16, 0.03, 14.0), + new LinearSales(24, 0.04, 13.0), + new LinearSales(37, 0.1, 14.5), + ]; + + return [ + new charts.Series( + id: 'Cheese', + colorFn: (LinearSales sales, _) => + charts.MaterialPalette.blue.shadeDefault, + domainFn: (LinearSales sales, _) => sales.year, + measureFn: (LinearSales sales, _) => sales.revenueShare, + radiusPxFn: (LinearSales sales, _) => sales.radius, + data: myFakeDesktopData), + new charts.Series( + id: 'Carrots', + colorFn: (LinearSales sales, _) => + charts.MaterialPalette.red.shadeDefault, + domainFn: (LinearSales sales, _) => sales.year, + measureFn: (LinearSales sales, _) => sales.revenueShare, + radiusPxFn: (LinearSales sales, _) => sales.radius, + data: myFakeTabletData), + new charts.Series( + id: 'Cucumbers', + colorFn: (LinearSales sales, _) => + charts.MaterialPalette.green.shadeDefault, + domainFn: (LinearSales sales, _) => sales.year, + measureFn: (LinearSales sales, _) => sales.revenueShare, + radiusPxFn: (LinearSales sales, _) => sales.radius, + data: myFakeMobileData), + new charts.Series( + id: 'Crayons', + colorFn: (LinearSales sales, _) => + charts.MaterialPalette.purple.shadeDefault, + domainFn: (LinearSales sales, _) => sales.year, + measureFn: (LinearSales sales, _) => sales.revenueShare, + radiusPxFn: (LinearSales sales, _) => sales.radius, + data: myFakeChromebookData), + new charts.Series( + id: 'Celery', + colorFn: (LinearSales sales, _) => + charts.MaterialPalette.indigo.shadeDefault, + domainFn: (LinearSales sales, _) => sales.year, + measureFn: (LinearSales sales, _) => sales.revenueShare, + radiusPxFn: (LinearSales sales, _) => sales.radius, + data: myFakeHomeData), + new charts.Series( + id: 'Cauliflower', + colorFn: (LinearSales sales, _) => + charts.MaterialPalette.gray.shadeDefault, + domainFn: (LinearSales sales, _) => sales.year, + measureFn: (LinearSales sales, _) => sales.revenueShare, + radiusPxFn: (LinearSales sales, _) => sales.radius, + data: myFakeOtherData), + ]; + } +} + +/// Sample linear data type. +class LinearSales { + final int year; + final double revenueShare; + final double radius; + + LinearSales(this.year, this.revenueShare, this.radius); +} \ No newline at end of file diff --git a/lib/common/widgets/charts/series_legend_with_measures.dart b/lib/common/widgets/charts/series_legend_with_measures.dart new file mode 100644 index 0000000..76334f8 --- /dev/null +++ b/lib/common/widgets/charts/series_legend_with_measures.dart @@ -0,0 +1,129 @@ +/// Bar chart with example of a legend with customized position, justification, +/// desired max rows, and padding. These options are shown as an example of how +/// to use the customizations, they do not necessary have to be used together in +/// this way. Choosing [end] as the position does not require the justification +/// to also be [endDrawArea]. +import 'package:flutter/material.dart'; +import 'package:charts_flutter/flutter.dart' as charts; + +/// Example that shows how to build a series legend that shows measure values +/// when a datum is selected. +/// +/// Also shows the option to provide a custom measure formatter. +class LegendWithMeasures extends StatelessWidget { + final List seriesList; + final bool animate; + + LegendWithMeasures(this.seriesList, {this.animate}); + + factory LegendWithMeasures.withSampleData() { + return new LegendWithMeasures( + _createSampleData(), + // Disable animations for image tests. + animate: false, + ); + } + + + @override + Widget build(BuildContext context) { + return new charts.BarChart( + seriesList, + animate: animate, + barGroupingType: charts.BarGroupingType.grouped, + // Add the legend behavior to the chart to turn on legends. + // This example shows how to optionally show measure and provide a custom + // formatter. + behaviors: [ + new charts.SeriesLegend( + // Positions for "start" and "end" will be left and right respectively + // for widgets with a build context that has directionality ltr. + // For rtl, "start" and "end" will be right and left respectively. + // Since this example has directionality of ltr, the legend is + // positioned on the right side of the chart. + position: charts.BehaviorPosition.end, + // By default, if the position of the chart is on the left or right of + // the chart, [horizontalFirst] is set to false. This means that the + // legend entries will grow as new rows first instead of a new column. + horizontalFirst: false, + // This defines the padding around each legend entry. + cellPadding: new EdgeInsets.only(right: 4.0, bottom: 4.0), + // Set show measures to true to display measures in series legend, + // when the datum is selected. + showMeasures: true, + // Optionally provide a measure formatter to format the measure value. + // If none is specified the value is formatted as a decimal. + measureFormatter: (num value) { + return value == null ? '-' : '${value}k'; + }, + ), + ], + ); + } + + /// Create series list with multiple series + static List> _createSampleData() { + final desktopSalesData = [ + new OrdinalSales('2014', 5), + new OrdinalSales('2015', 25), + new OrdinalSales('2016', 100), + new OrdinalSales('2017', 75), + ]; + + final tabletSalesData = [ + new OrdinalSales('2014', 25), + new OrdinalSales('2015', 50), + // Purposely have a null data for 2016 to show the null value format. + new OrdinalSales('2017', 20), + ]; + + final mobileSalesData = [ + new OrdinalSales('2014', 10), + new OrdinalSales('2015', 15), + new OrdinalSales('2016', 50), + new OrdinalSales('2017', 45), + ]; + + final otherSalesData = [ + new OrdinalSales('2014', 20), + new OrdinalSales('2015', 35), + new OrdinalSales('2016', 15), + new OrdinalSales('2017', 10), + ]; + + return [ + new charts.Series( + id: 'Lancaster', + domainFn: (OrdinalSales sales, _) => sales.year, + measureFn: (OrdinalSales sales, _) => sales.sales, + data: desktopSalesData, + ), + new charts.Series( + id: 'Morecambe', + domainFn: (OrdinalSales sales, _) => sales.year, + measureFn: (OrdinalSales sales, _) => sales.sales, + data: tabletSalesData, + ), + new charts.Series( + id: 'Mars', + domainFn: (OrdinalSales sales, _) => sales.year, + measureFn: (OrdinalSales sales, _) => sales.sales, + data: mobileSalesData, + ), + new charts.Series( + id: 'Other', + domainFn: (OrdinalSales sales, _) => sales.year, + measureFn: (OrdinalSales sales, _) => sales.sales, + data: otherSalesData, + ), + ]; + } +} + +/// Sample ordinal data type. +class OrdinalSales { + final String year; + final int sales; + + OrdinalSales(this.year, this.sales); +} \ No newline at end of file diff --git a/lib/pages/receipt_page.dart b/lib/pages/receipt_page.dart index d9c62b8..343072e 100644 --- a/lib/pages/receipt_page.dart +++ b/lib/pages/receipt_page.dart @@ -565,7 +565,7 @@ class ReceiptPageState extends State { ), Padding( - padding: EdgeInsets.fromLTRB(0.0, 40.0, 0.0, 0.0), + padding: EdgeInsets.fromLTRB(0.0, 20.0, 0.0, 0.0), child: Container( height: 65.0, child: RaisedButton( diff --git a/lib/pages/stats_page.dart b/lib/pages/stats_page.dart index adcbdb4..aefe483 100644 --- a/lib/pages/stats_page.dart +++ b/lib/pages/stats_page.dart @@ -1,4 +1,3 @@ - import 'package:flutter/material.dart'; import 'package:local_spend/common/platform/platform_scaffold.dart'; import 'package:shared_preferences/shared_preferences.dart'; @@ -6,6 +5,13 @@ import 'package:local_spend/common/functions/logout.dart'; import 'package:url_launcher/url_launcher.dart'; import 'package:local_spend/common/functions/customAbout.dart' as custom; import 'package:local_spend/common/functions/showDialogTwoButtons.dart'; +import 'package:local_spend/common/widgets/charts/donut_chart.dart'; +import 'package:local_spend/common/widgets/charts/outside_label.dart'; +import 'package:local_spend/common/widgets/charts/auto_label.dart'; +import 'package:local_spend/common/widgets/charts/grouped_bar_chart.dart'; +import 'package:local_spend/common/widgets/charts/scatter_bucketingAxis_legend.dart'; +import 'package:local_spend/common/widgets/charts/numeric_line_bar_combo.dart'; +import 'package:local_spend/common/widgets/charts/series_legend_with_measures.dart'; const URL = "https://flutter.io/"; const demonstration = false; @@ -52,12 +58,171 @@ class StatsPageState extends State { iconTheme: IconThemeData(color: Colors.black), ), - body: Container( - padding: EdgeInsets.fromLTRB(0, 15, 0, 0), - child: Column( + + body : Container( + padding: EdgeInsets.fromLTRB(0, 0, 0, 0), + child: ListView( children: [ // some graphs and charts here etc - Center(child : Text("(imagine this is a really cool graph!)"),) +// Container( +// padding: EdgeInsets.fromLTRB(0.0,17,0.0,0.0), +// child : Text( +// "Really Cool Chart", +// textAlign: TextAlign.center, +// style: TextStyle( +// fontSize: 22.0, +// color: Colors.black, +// fontWeight: FontWeight.bold, +// ), +// ), +// ), +// +// Container( +// height: 250, +//// width: 250, +// child: new DonutPieChart.withSampleData() +// ), + + Container( + padding: EdgeInsets.fromLTRB(0.0,17,0.0,0.0), + child : Text( + "GroupedBarChart", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22.0, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + ), + + Container( + padding: EdgeInsets.symmetric(horizontal: 10), + height: 200, +// width: 250, + child: new GroupedBarChart.withSampleData() + ), + + Container( + padding: EdgeInsets.fromLTRB(0.0,17,0.0,0.0), + child : Text( + "BucketingAxisScatterPlotChart", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22.0, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + ), + + Container( + padding: EdgeInsets.symmetric(horizontal: 10), + height: 200, +// width: 250, + child: new BucketingAxisScatterPlotChart.withSampleData() + ), + + Container( + padding: EdgeInsets.fromLTRB(0.0,20,0.0,0.0), + child : Text( + "PieOutsideLabelChart", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22.0, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + ), + + Container( + padding: EdgeInsets.symmetric(horizontal: 10), + height: 200, +// width: 250, + child: new PieOutsideLabelChart.withSampleData() + ), + + Container( + padding: EdgeInsets.fromLTRB(0.0,17,0.0,0.0), + child : Text( + "DonutAutoLabelChart", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22.0, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + ), + + Container( + padding: EdgeInsets.symmetric(horizontal: 10), + height: 200, +// width: 250, + child: new DonutAutoLabelChart.withSampleData() + ), + + Container( + padding: EdgeInsets.fromLTRB(0.0,17,0.0,0.0), + child : Text( + "DonutPieChart", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22.0, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + ), + + Container( + padding: EdgeInsets.symmetric(horizontal: 10), + height: 200, +// width: 250, + child: new DonutPieChart.withSampleData() + ), + + Container( + padding: EdgeInsets.fromLTRB(0.0,17,0.0,0.0), + child : Text( + "NumericComboLineBarChart", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22.0, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + ), + + Container( + padding: EdgeInsets.symmetric(horizontal: 10), + height: 200, +// width: 250, + child: new NumericComboLineBarChart.withSampleData() + ), + + Container( + padding: EdgeInsets.fromLTRB(0.0,17,0.0,0.0), + child : Text( + "LegendWithMeasures", + textAlign: TextAlign.center, + style: TextStyle( + fontSize: 22.0, + color: Colors.black, + fontWeight: FontWeight.bold, + ), + ), + ), + + Container( + padding: EdgeInsets.symmetric(horizontal: 10), + height: 200, +// width: 250, + child: new LegendWithMeasures.withSampleData() + ), + ], ), ), diff --git a/pubspec.lock b/pubspec.lock index b229dc3..cc8d2b8 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -92,6 +92,20 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "1.1.2" + charts_common: + dependency: transitive + description: + name: charts_common + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.0" + charts_flutter: + dependency: "direct main" + description: + name: charts_flutter + url: "https://pub.dartlang.org" + source: hosted + version: "0.6.0" code_builder: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index a5d9364..c05bf61 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -24,7 +24,7 @@ dependencies: datetime_picker_formfield: ^0.1.8 flutter_linkify: ^1.0.3 flutter_fadein: ^1.1.1 - + charts_flutter: ^0.6.0 # The following adds the Cupertino Icons font to your application. # Use with the CupertinoIcons class for iOS style icons. cupertino_icons: ^0.1.2