Skip to content

Commit

Permalink
feat: Added statistics
Browse files Browse the repository at this point in the history
  • Loading branch information
styrix560 committed Sep 10, 2024
1 parent 9de4650 commit 3315361
Show file tree
Hide file tree
Showing 6 changed files with 221 additions and 1 deletion.
5 changes: 4 additions & 1 deletion lib/main.dart
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import "package:bbs4/types/config.dart";
import "package:bbs4/types/global_data.dart";
import "package:bbs4/widgets/statistics.dart";
import "package:flutter/foundation.dart";
import "package:flutter/material.dart";
import "package:flutter_hooks/flutter_hooks.dart";
Expand Down Expand Up @@ -60,7 +61,7 @@ class MainApp extends HookWidget {

@override
Widget build(BuildContext context) {
final tabController = useTabController(initialLength: 2);
final tabController = useTabController(initialLength: 3);

return Scaffold(
appBar: AppBar(
Expand All @@ -71,6 +72,7 @@ class MainApp extends HookWidget {
bottom: TabBar(controller: tabController, tabs: const [
Tab(text: "Buchungen"),
Tab(text: "Überblick"),
Tab(text: "Statistiken"),
]),
),
body: Padding(
Expand All @@ -81,6 +83,7 @@ class MainApp extends HookWidget {
child: BookingsView(),
),
OverviewWidget(tabController),
StatisticsWidget(),
]),
),
);
Expand Down
204 changes: 204 additions & 0 deletions lib/widgets/statistics.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1,204 @@
import "package:fl_chart/fl_chart.dart";
import "package:flutter/material.dart";
import "package:flutter_hooks/flutter_hooks.dart";
import "package:supernova/supernova.dart";

import "../types/booking.dart";
import "../types/global_data.dart";
import "../types/price_type.dart";

class StatisticsWidget extends HookWidget {
const StatisticsWidget({super.key});

@override
Widget build(BuildContext context) {
final globalData = GlobalData();
useListenable(globalData.isTransactionInProgress);
useListenable(GlobalData.currentBookingTime);

final bookings = globalData.bookings.value;
final seatsSoldTotal = bookings.map((booking) => booking.seats.length).sum;
final seatsSoldPerPriceType = {
for (final priceType in PriceType.values)
priceType: bookings
.where((booking) => booking.priceType == priceType)
.map((booking) => booking.seats.length)
.sum,
};
final moneyMadeTotal = bookings.map((booking) => booking.pricePaid).sum;
final moneyMadeByPriceType = {
for (final priceType in [PriceType.normal, PriceType.reduced])
priceType: bookings
.where((booking) => booking.priceType == priceType)
.map((booking) => booking.pricePaid)
.sum,
};
final seatsPerGrade = <int?, int>{};
bookings.map(getGradeFromBooking).forEach((e) {
if (seatsPerGrade.containsKey(e)) {
seatsPerGrade[e] = seatsPerGrade[e]! + 1;
} else {
seatsPerGrade[e] = 1;
}
});

return SingleChildScrollView(
child: Column(
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
// Text("Sitze verkauft: $seatsSoldTotal"),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
// children: [
// for (final entry in seatsSoldPerPriceType.entries)
// Text("${entry.key.germanName}: ${entry.value}"),
// ],
// ),
// Divider(
// color: Colors.black,
// ),
// Text("Geld eingenommen: $moneyMadeTotal"),
// Row(
// mainAxisAlignment: MainAxisAlignment.spaceAround,
// children: [
// for (final entry in moneyMadeByPriceType.entries)
// Text("${entry.key.germanName}: ${entry.value}"),
// ],
// ),
Column(
children: [
Text("Sitze verkauft: $seatsSoldTotal"),
SizedBox(
width: 400,
height: 400,
child:
PieChart(PieChartData(centerSpaceRadius: 0, sections: [
for (final entry in seatsSoldPerPriceType.entries)
PieChartSectionData(
title: "${entry.value}",
value: entry.value.toDouble(),
radius: 80,
color: getColour(entry.key),
),
])),
),
],
),
SizedBox(
height: 400,
child: VerticalDivider(
color: Colors.black,
),
),
Column(
children: [
Text("Eingenommenes Geld: $moneyMadeTotal€"),
SizedBox(
width: 400,
height: 400,
child:
PieChart(PieChartData(centerSpaceRadius: 0, sections: [
for (final entry in moneyMadeByPriceType.entries)
PieChartSectionData(
title: "${entry.value}€",
value: entry.value.toDouble(),
radius: 80,
color: getColour(entry.key),
),
])),
),
],
),
SizedBox(
height: 400,
child: VerticalDivider(
color: Colors.black,
),
),
Column(
children: [
Text("Sitze pro Klassenstufe"),
SizedBox(
width: 400,
height: 400,
child:
PieChart(PieChartData(centerSpaceRadius: 0, sections: [
for (final entry in seatsPerGrade.entries)
PieChartSectionData(
title: "${entry.value}",
value: entry.value.toDouble(),
badgeWidget: Text("KS " + (entry.key ?? "nicht zugeordnet").toString()),
badgePositionPercentageOffset: 1.3,
radius: 80,
color: getColourForGrade(entry.key),
),
])),
),
],
),
],
),
Padding(
padding: const EdgeInsets.only(left: 32),
child: Column(
children: [
for (final priceType in PriceType.values)
Row(
children: [
Padding(
padding: const EdgeInsets.only(right: 8),
child: SizedBox(
width: 10,
height: 10,
child: Container(
color: getColour(priceType),
),
),
),
Text(priceType.germanName)
],
),
],
),
),
],
),
);
}
}

int? getGradeFromBooking(Booking booking) {
final grade = booking.className.characters.where(isDigit).join();
if (grade.isEmpty) return null;
return int.parse(grade);
}

bool isDigit(String c) => double.tryParse(c) != null;

Color getColour(PriceType priceType) {
switch (priceType) {
case PriceType.normal:
return Colors.green;
case PriceType.reduced:
return Colors.yellow;
case PriceType.free:
return Colors.red;
}
}

Color getColourForGrade(int? grade) {
if (grade == null) return Colors.grey;
const colours = [
Colors.blue,
Colors.yellow,
Colors.purple,
Colors.pink,
Colors.orange,
Colors.green,
Colors.red,
Colors.purpleAccent
];
return colours[grade % colours.length];
}
8 changes: 8 additions & 0 deletions pubspec.lock
Original file line number Diff line number Diff line change
Expand Up @@ -346,6 +346,14 @@ packages:
url: "https://pub.dev"
source: hosted
version: "1.1.0"
fl_chart:
dependency: "direct main"
description:
name: fl_chart
sha256: "94307bef3a324a0d329d3ab77b2f0c6e5ed739185ffc029ed28c0f9b019ea7ef"
url: "https://pub.dev"
source: hosted
version: "0.69.0"
flutter:
dependency: "direct main"
description: flutter
Expand Down
1 change: 1 addition & 0 deletions pubspec.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ environment:
dependencies:
collection: ^1.18.0
encrypt: ^5.0.3
fl_chart: ^0.69.0
flutter:
sdk: flutter
flutter_hooks: ^0.20.5
Expand Down
3 changes: 3 additions & 0 deletions windows/flutter/generated_plugin_registrant.cc
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,9 @@

#include "generated_plugin_registrant.h"

#include <printing/printing_plugin.h>

void RegisterPlugins(flutter::PluginRegistry* registry) {
PrintingPluginRegisterWithRegistrar(
registry->GetRegistrarForPlugin("PrintingPlugin"));
}
1 change: 1 addition & 0 deletions windows/flutter/generated_plugins.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
#

list(APPEND FLUTTER_PLUGIN_LIST
printing
)

list(APPEND FLUTTER_FFI_PLUGIN_LIST
Expand Down

0 comments on commit 3315361

Please sign in to comment.