Dashboard

This commit is contained in:
Hillel Coren 2018-11-12 12:04:10 +02:00
parent 2633a2e1a1
commit 0f9355f17e
3 changed files with 80 additions and 58 deletions

View File

@ -4,6 +4,15 @@ import 'package:memoize/memoize.dart';
import 'package:built_collection/built_collection.dart';
import 'package:invoiceninja_flutter/data/models/models.dart';
class ChartDataGroup {
ChartDataGroup(this.name);
final String name;
final List<ChartMoneyData> rawSeries = [];
dynamic chartSeries;
double total = 0.0;
}
class ChartMoneyData {
ChartMoneyData(this.date, this.amount);
@ -32,14 +41,17 @@ var memoizedChartOutstandingQuotes = memo4((CompanyEntity company,
clientMap: clientMap,
isQuote: true));
List<ChartMoneyData> chartOutstandingInvoices({
List<ChartDataGroup> chartOutstandingInvoices({
CompanyEntity company,
DashboardUIState settings,
BuiltMap<int, InvoiceEntity> invoiceMap,
BuiltMap<int, ClientEntity> clientMap,
bool isQuote = false,
}) {
final Map<String, double> totals = {};
final Map<String, Map<String, double>> totals = {};
const STATUS_ACTIVE = 'active';
const STATUS_OUTSTANDING = 'outstanding';
invoiceMap.forEach((int, invoice) {
final client =
@ -61,26 +73,41 @@ List<ChartMoneyData> chartOutstandingInvoices({
// skip it
} else {
if (totals[invoice.invoiceDate] == null) {
totals[invoice.invoiceDate] = 0.0;
totals[STATUS_ACTIVE][invoice.invoiceDate] = 0.0;
totals[STATUS_OUTSTANDING][invoice.invoiceDate] = 0.0;
}
totals[invoice.invoiceDate] += invoice.amount;
totals[STATUS_ACTIVE][invoice.invoiceDate] += invoice.amount;
totals[STATUS_OUTSTANDING][invoice.invoiceDate] += invoice.balance;
}
});
final List<ChartMoneyData> data = [];
final ChartDataGroup activeData = ChartDataGroup(STATUS_ACTIVE);
final ChartDataGroup outstandingData = ChartDataGroup(STATUS_OUTSTANDING);
var date = DateTime.parse(settings.startDate(company));
final endDate = DateTime.parse(settings.endDate(company));
while (!date.isAfter(endDate)) {
final key = convertDateTimeToSqlDate(date);
if (totals.containsKey(key)) {
data.add(ChartMoneyData(date, totals[key]));
if (totals[STATUS_ACTIVE].containsKey(key)) {
activeData.rawSeries.add(ChartMoneyData(date, totals[STATUS_ACTIVE][key]));
activeData.total += totals[STATUS_ACTIVE][key];
outstandingData.rawSeries
.add(ChartMoneyData(date, totals[STATUS_OUTSTANDING][key]));
outstandingData.total += totals[STATUS_OUTSTANDING][key];
} else {
data.add(ChartMoneyData(date, 0.0));
activeData.rawSeries.add(ChartMoneyData(date, 0.0));
outstandingData.rawSeries.add(ChartMoneyData(date, 0.0));
}
date = date.add(Duration(days: 1));
}
final List<ChartDataGroup> data = [
activeData,
outstandingData,
];
return data;
}

View File

@ -1,21 +1,18 @@
import 'package:flutter/material.dart';
import 'package:flutter_redux/flutter_redux.dart';
import 'package:invoiceninja_flutter/redux/app/app_state.dart';
import 'package:invoiceninja_flutter/redux/dashboard/dashboard_selectors.dart';
import 'package:invoiceninja_flutter/ui/app/form_card.dart';
import 'package:charts_flutter/flutter.dart' as charts;
import 'package:invoiceninja_flutter/utils/formatting.dart';
class DashboardChart extends StatefulWidget {
const DashboardChart(
{this.series,
this.amount,
this.previousAmount,
{this.data,
this.title,
this.currencyId});
final List<charts.Series> series;
final double previousAmount;
final double amount;
final List<ChartDataGroup> data;
final String title;
final int currencyId;
@ -66,6 +63,7 @@ class _DashboardChartState extends State<DashboardChart> {
? charts.MaterialPalette.white
: charts.MaterialPalette.gray.shade700;
/*
final chart = charts.TimeSeriesChart(
widget.series,
animate: true,
@ -109,6 +107,7 @@ class _DashboardChartState extends State<DashboardChart> {
final String changeString = widget.amount == 0 || widget.previousAmount == 0
? ''
: '$changeAmount ($changePercent)';
*/
return FormCard(
children: <Widget>[
@ -116,6 +115,7 @@ class _DashboardChartState extends State<DashboardChart> {
padding: EdgeInsets.symmetric(vertical: 14.0, horizontal: 4.0),
child: Column(
children: <Widget>[
Text(widget.title,),
Row(
crossAxisAlignment: CrossAxisAlignment.start,
children: <Widget>[
@ -125,6 +125,7 @@ class _DashboardChartState extends State<DashboardChart> {
children: <Widget>[
Text(widget.title,
style: Theme.of(context).textTheme.subhead),
/*
Text(
formatNumber(widget.amount, context,
currencyId: widget.currencyId),
@ -138,6 +139,7 @@ class _DashboardChartState extends State<DashboardChart> {
fontWeight: FontWeight.bold,
),
),
*/
],
),
),
@ -158,7 +160,7 @@ class _DashboardChartState extends State<DashboardChart> {
height: 200.0,
child: Padding(
padding: const EdgeInsets.only(top: 10.0),
child: chart,
//child: chart,
),
),
],

View File

@ -112,8 +112,8 @@ class DashboardPanels extends StatelessWidget {
final data = memoizedChartOutstandingInvoices(state.selectedCompany,
settings, state.invoiceState.map, state.clientState.map);
final series = [
charts.Series<ChartMoneyData, DateTime>(
data.forEach((dataGroup) {
dataGroup.chartSeries = charts.Series<ChartMoneyData, DateTime>(
domainFn: (ChartMoneyData chartData, _) => chartData.date,
measureFn: (ChartMoneyData chartData, _) => chartData.amount,
colorFn: (ChartMoneyData chartData, _) =>
@ -122,49 +122,40 @@ class DashboardPanels extends StatelessWidget {
displayName: settings.enableComparison
? localization.current
: localization.invoices,
data: data,
),
];
double total = 0.0;
double previousTotal = 0.0;
data.forEach((dynamic item) {
total += item.amount;
});
if (settings.enableComparison) {
final offsetData = memoizedChartOutstandingInvoices(
state.selectedCompany,
settings.rebuild((b) => b..offset += 1),
state.invoiceState.map,
state.clientState.map);
final List<ChartMoneyData> previousData = [];
for (int i = 0; i < min(data.length, offsetData.length); i++) {
previousData.add(ChartMoneyData(data[i].date, offsetData[i].amount));
}
series.add(
charts.Series<ChartMoneyData, DateTime>(
domainFn: (ChartMoneyData chartData, _) => chartData.date,
measureFn: (ChartMoneyData chartData, _) => chartData.amount,
colorFn: (ChartMoneyData chartData, _) =>
charts.MaterialPalette.gray.shadeDefault,
id: DashboardChart.PERIOD_PREVIOUS,
displayName: localization.previous,
data: previousData,
),
data: dataGroup.rawSeries,
);
previousData.forEach((dynamic item) {
previousTotal += item.amount;
});
}
if (settings.enableComparison) {
final offsetData = memoizedChartOutstandingInvoices(
state.selectedCompany,
settings.rebuild((b) => b..offset += 1),
state.invoiceState.map,
state.clientState.map);
final List<ChartMoneyData> previousData = [];
for (int i = 0;
i < min(dataGroup.rawSeries.length, offsetData.length);
i++) {
previousData.add(ChartMoneyData(dataGroup.rawSeries[i].date,
offsetData[data.indexOf(dataGroup)].rawSeries[i].amount));
}
dataGroup.chartSeries.add(
charts.Series<ChartMoneyData, DateTime>(
domainFn: (ChartMoneyData chartData, _) => chartData.date,
measureFn: (ChartMoneyData chartData, _) => chartData.amount,
colorFn: (ChartMoneyData chartData, _) =>
charts.MaterialPalette.gray.shadeDefault,
id: DashboardChart.PERIOD_PREVIOUS,
displayName: localization.previous,
data: previousData,
),
);
}
});
return DashboardChart(
series: series,
amount: total,
previousAmount: previousTotal,
data: data,
title: localization.invoices,
currencyId: settings.currencyId > 0
? settings.currencyId
@ -172,6 +163,7 @@ class DashboardPanels extends StatelessWidget {
);
}
/*
Widget _paymentChart(BuildContext context) {
if (!viewModel.state.paymentState.isLoaded) {
return LoadingIndicator(useCard: true);
@ -324,6 +316,7 @@ class DashboardPanels extends StatelessWidget {
: state.selectedCompany.currencyId,
);
}
*/
@override
Widget build(BuildContext context) {
@ -335,8 +328,8 @@ class DashboardPanels extends StatelessWidget {
height: 74.0,
),
_invoiceChart(context),
_paymentChart(context),
_quoteChart(context),
//_paymentChart(context),
//_quoteChart(context),
],
),
ConstrainedBox(