Dashboard
This commit is contained in:
parent
82fd011336
commit
384c0dd5e8
|
|
@ -196,6 +196,11 @@ abstract class PaymentEntity extends Object
|
|||
@override
|
||||
double get listDisplayAmount => amount;
|
||||
|
||||
bool isBetween(String startDate, String endDate) {
|
||||
return startDate.compareTo(paymentDate) <= 0 &&
|
||||
endDate.compareTo(paymentDate) == 1;
|
||||
}
|
||||
|
||||
@override
|
||||
FormatNumberType get listDisplayAmountType => FormatNumberType.money;
|
||||
|
||||
|
|
|
|||
|
|
@ -51,3 +51,42 @@ List<ChartMoneyData> chartOutstandingInvoices(
|
|||
|
||||
return data;
|
||||
}
|
||||
|
||||
|
||||
var memoizedChartPayments = memo2(
|
||||
(DashboardUIState settings, BuiltMap<int, PaymentEntity> paymentMap) =>
|
||||
chartPayments(settings, paymentMap));
|
||||
|
||||
List<ChartMoneyData> chartPayments(
|
||||
DashboardUIState settings, BuiltMap<int, PaymentEntity> paymentMap) {
|
||||
final Map<String, double> totals = {};
|
||||
|
||||
paymentMap.forEach((int, payment) {
|
||||
if (payment.isDeleted) {
|
||||
// skip it
|
||||
} else if (!payment.isBetween(settings.startDate, settings.endDate)) {
|
||||
// skip it
|
||||
} else {
|
||||
if (totals[payment.paymentDate] == null) {
|
||||
totals[payment.paymentDate] = 0.0;
|
||||
}
|
||||
totals[payment.paymentDate] += payment.amount;
|
||||
}
|
||||
});
|
||||
|
||||
final List<ChartMoneyData> data = [];
|
||||
|
||||
var date = DateTime.parse(settings.startDate);
|
||||
final endDate = DateTime.parse(settings.endDate);
|
||||
while (date.isBefore(endDate)) {
|
||||
final key = convertDateTimeToSqlDate(date);
|
||||
if (totals.containsKey(key)) {
|
||||
data.add(ChartMoneyData(date, totals[key]));
|
||||
} else {
|
||||
data.add(ChartMoneyData(date, 0.0));
|
||||
}
|
||||
date = date.add(Duration(days: 1));
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -67,17 +67,12 @@ class _DashboardChartState extends State<DashboardChart> {
|
|||
final bool isIncrease = widget.amount >= widget.previousAmount;
|
||||
final String changeAmount = (isIncrease ? '+' : '') +
|
||||
formatNumber(widget.amount - widget.previousAmount, context);
|
||||
String changePercent;
|
||||
if (widget.amount == 0) {
|
||||
changePercent = '0%';
|
||||
} else if (widget.previousAmount == 0) {
|
||||
changePercent = '∞%';
|
||||
} else {
|
||||
changePercent = (isIncrease ? '+' : '-') +
|
||||
formatNumber(widget.previousAmount / widget.amount * 100, context,
|
||||
formatNumberType: FormatNumberType.percent);
|
||||
}
|
||||
final String changeString = '$changeAmount ($changePercent)';
|
||||
final changePercent = (isIncrease ? '+' : '-') +
|
||||
formatNumber(widget.previousAmount / widget.amount * 100, context,
|
||||
formatNumberType: FormatNumberType.percent);
|
||||
final String changeString = widget.amount == 0 || widget.previousAmount == 0
|
||||
? ''
|
||||
: '$changeAmount ($changePercent)';
|
||||
|
||||
return FormCard(
|
||||
children: <Widget>[
|
||||
|
|
|
|||
|
|
@ -79,10 +79,10 @@ class DashboardPanels extends StatelessWidget {
|
|||
|
||||
final series = [
|
||||
charts.Series<ChartMoneyData, DateTime>(
|
||||
domainFn: (ChartMoneyData clickData, _) => clickData.date,
|
||||
measureFn: (ChartMoneyData clickData, _) => clickData.amount,
|
||||
colorFn: (ChartMoneyData clickData, _) =>
|
||||
charts.MaterialPalette.blue.shadeDefault,
|
||||
domainFn: (ChartMoneyData chartData, _) => chartData.date,
|
||||
measureFn: (ChartMoneyData chartData, _) => chartData.amount,
|
||||
colorFn: (ChartMoneyData chartData, _) =>
|
||||
charts.MaterialPalette.blue.shadeDefault,
|
||||
id: 'invoices',
|
||||
displayName: settings.enableComparison
|
||||
? localization.currentPeriod
|
||||
|
|
@ -109,10 +109,10 @@ class DashboardPanels extends StatelessWidget {
|
|||
|
||||
series.add(
|
||||
charts.Series<ChartMoneyData, DateTime>(
|
||||
domainFn: (ChartMoneyData clickData, _) => clickData.date,
|
||||
measureFn: (ChartMoneyData clickData, _) => clickData.amount,
|
||||
colorFn: (ChartMoneyData clickData, _) =>
|
||||
charts.MaterialPalette.gray.shadeDefault,
|
||||
domainFn: (ChartMoneyData chartData, _) => chartData.date,
|
||||
measureFn: (ChartMoneyData chartData, _) => chartData.amount,
|
||||
colorFn: (ChartMoneyData chartData, _) =>
|
||||
charts.MaterialPalette.gray.shadeDefault,
|
||||
id: 'previous',
|
||||
displayName: localization.previousPeriod,
|
||||
data: previousData,
|
||||
|
|
@ -131,12 +131,74 @@ class DashboardPanels extends StatelessWidget {
|
|||
title: localization.invoices);
|
||||
}
|
||||
|
||||
Widget _paymentChart(BuildContext context) {
|
||||
final localization = AppLocalization.of(context);
|
||||
final settings = viewModel.dashboardUIState;
|
||||
|
||||
final data = memoizedChartPayments(
|
||||
settings, viewModel.state.paymentState.map);
|
||||
|
||||
final series = [
|
||||
charts.Series<ChartMoneyData, DateTime>(
|
||||
domainFn: (ChartMoneyData chartData, _) => chartData.date,
|
||||
measureFn: (ChartMoneyData chartData, _) => chartData.amount,
|
||||
colorFn: (ChartMoneyData chartData, _) =>
|
||||
charts.MaterialPalette.blue.shadeDefault,
|
||||
id: 'payments',
|
||||
displayName: settings.enableComparison
|
||||
? localization.currentPeriod
|
||||
: localization.payments,
|
||||
data: data,
|
||||
),
|
||||
];
|
||||
|
||||
double total = 0.0;
|
||||
double previousTotal = 0.0;
|
||||
data.forEach((dynamic item) {
|
||||
total += item.amount;
|
||||
});
|
||||
|
||||
if (settings.enableComparison) {
|
||||
final offsetData = memoizedChartOutstandingInvoices(
|
||||
viewModel.dashboardUIState.rebuild((b) => b..offset += 1),
|
||||
viewModel.state.invoiceState.map);
|
||||
|
||||
final List<ChartMoneyData> previousData = [];
|
||||
for (int i = 0; i < data.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: 'previous',
|
||||
displayName: localization.previousPeriod,
|
||||
data: previousData,
|
||||
),
|
||||
);
|
||||
|
||||
previousData.forEach((dynamic item) {
|
||||
previousTotal += item.amount;
|
||||
});
|
||||
}
|
||||
|
||||
return DashboardChart(
|
||||
series: series,
|
||||
amount: total,
|
||||
previousAmount: previousTotal,
|
||||
title: localization.payments);
|
||||
}
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return ListView(
|
||||
children: <Widget>[
|
||||
_header(context),
|
||||
_invoiceChart(context),
|
||||
_paymentChart(context),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue