Dashboard
This commit is contained in:
parent
2633a2e1a1
commit
0f9355f17e
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
),
|
||||
),
|
||||
],
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
Loading…
Reference in New Issue