2024-05-06 17:28:10 +02:00
|
|
|
import 'package:flutter/cupertino.dart';
|
2024-06-03 12:46:40 +02:00
|
|
|
import 'package:flutter/material.dart';
|
2024-05-06 17:28:10 +02:00
|
|
|
import 'package:syncfusion_flutter_charts/charts.dart';
|
|
|
|
|
2024-05-24 14:04:26 +02:00
|
|
|
// Widget zur Erstellung eines gestapelten Säulendiagramms
|
2024-05-06 17:28:10 +02:00
|
|
|
class StackedColumnChart extends StatelessWidget {
|
2024-05-24 14:04:26 +02:00
|
|
|
final List<double> lowerValues; // Liste der unteren Werte für das Diagramm
|
|
|
|
final List<double> upperValues; // Liste der oberen Werte für das Diagramm
|
2024-05-06 17:28:10 +02:00
|
|
|
|
|
|
|
const StackedColumnChart({
|
|
|
|
super.key,
|
|
|
|
required this.lowerValues,
|
|
|
|
required this.upperValues,
|
|
|
|
});
|
|
|
|
|
|
|
|
@override
|
|
|
|
Widget build(BuildContext context) {
|
|
|
|
return SfCartesianChart(
|
2024-05-20 16:34:31 +02:00
|
|
|
legend: const Legend(
|
2024-05-24 14:04:26 +02:00
|
|
|
isVisible: true,
|
|
|
|
position: LegendPosition.top,
|
2024-05-20 16:34:31 +02:00
|
|
|
),
|
2024-05-06 17:28:10 +02:00
|
|
|
primaryXAxis: const CategoryAxis(
|
|
|
|
title: AxisTitle(text: 'Jahr'),
|
|
|
|
),
|
|
|
|
primaryYAxis: const NumericAxis(
|
|
|
|
title: AxisTitle(text: 'Euro'),
|
|
|
|
),
|
|
|
|
series: <CartesianSeries>[
|
2024-05-24 14:04:26 +02:00
|
|
|
// Serie für die Einzahlungen (untere Werte)
|
2024-05-06 17:28:10 +02:00
|
|
|
StackedColumnSeries<SalesData, int>(
|
|
|
|
dataSource: _getLowerChartData(),
|
|
|
|
xValueMapper: (SalesData sales, _) => sales.year,
|
|
|
|
yValueMapper: (SalesData sales, _) => sales.value,
|
2024-05-20 16:34:31 +02:00
|
|
|
name: 'Einzahlungen',
|
2024-05-24 14:04:26 +02:00
|
|
|
color: CupertinoColors.systemGrey.darkHighContrastColor,
|
2024-05-06 17:28:10 +02:00
|
|
|
),
|
2024-05-24 14:04:26 +02:00
|
|
|
// Serie für die Zinsen (obere Werte)
|
2024-05-06 17:28:10 +02:00
|
|
|
StackedColumnSeries<SalesData, int>(
|
|
|
|
dataSource: _getUpperChartData(),
|
|
|
|
xValueMapper: (SalesData sales, _) => sales.year,
|
|
|
|
yValueMapper: (SalesData sales, _) => sales.value,
|
2024-05-20 16:34:31 +02:00
|
|
|
name: 'Zinsen',
|
2024-05-24 14:04:26 +02:00
|
|
|
color: CupertinoColors.systemGreen.highContrastColor,
|
2024-05-06 17:28:10 +02:00
|
|
|
),
|
|
|
|
],
|
2024-05-24 14:04:26 +02:00
|
|
|
// Konfiguration für die Interaktivität des Diagramms
|
2024-05-20 16:34:31 +02:00
|
|
|
trackballBehavior: TrackballBehavior(
|
|
|
|
enable: true,
|
|
|
|
tooltipSettings: const InteractiveTooltip(enable: true),
|
|
|
|
activationMode: ActivationMode.singleTap,
|
|
|
|
hideDelay: 2000,
|
|
|
|
),
|
2024-05-06 17:28:10 +02:00
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2024-05-24 14:04:26 +02:00
|
|
|
// Methode zur Erstellung der Daten für die untere Serie (Einzahlungen)
|
2024-05-06 17:28:10 +02:00
|
|
|
List<SalesData> _getLowerChartData() {
|
|
|
|
List<SalesData> chartData = [];
|
|
|
|
for (int i = 0; i < lowerValues.length; i++) {
|
|
|
|
chartData.add(SalesData(i + 1, lowerValues[i]));
|
|
|
|
}
|
|
|
|
return chartData;
|
|
|
|
}
|
2024-05-24 14:04:26 +02:00
|
|
|
|
|
|
|
// Methode zur Erstellung der Daten für die obere Serie (Zinsen)
|
2024-05-06 17:28:10 +02:00
|
|
|
List<SalesData> _getUpperChartData() {
|
|
|
|
List<SalesData> chartData = [];
|
|
|
|
for (int i = 0; i < upperValues.length; i++) {
|
|
|
|
chartData.add(SalesData(i + 1, upperValues[i]));
|
|
|
|
}
|
|
|
|
return chartData;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2024-05-24 14:04:26 +02:00
|
|
|
// Klasse zur Modellierung der Datenpunkte im Diagramm
|
2024-05-06 17:28:10 +02:00
|
|
|
class SalesData {
|
|
|
|
final int year;
|
|
|
|
final double value;
|
|
|
|
|
|
|
|
SalesData(this.year, this.value);
|
|
|
|
}
|
2024-06-03 12:46:40 +02:00
|
|
|
|
|
|
|
// Widget, welches das Diagramm auf eine neue Seite auslagert
|
|
|
|
@override
|
|
|
|
Widget buildChartPage(BuildContext context, List<double> investedMoneyList, List<double> compoundInterestList) {
|
|
|
|
return Scaffold(
|
|
|
|
body: CustomScrollView(
|
|
|
|
slivers: <Widget>[
|
|
|
|
SliverToBoxAdapter(
|
|
|
|
child: Container(
|
|
|
|
padding: EdgeInsets.only(left: 10, right: 10, top: MediaQuery.of(context).padding.top + 10),
|
|
|
|
child: Row(
|
|
|
|
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
|
|
|
children: [
|
|
|
|
IconButton(
|
|
|
|
icon: const Icon(CupertinoIcons.chevron_left, size: 15), // Zurück-Pfeil
|
|
|
|
onPressed: () {
|
|
|
|
Navigator.pop(context);
|
|
|
|
},
|
|
|
|
),
|
|
|
|
const Text(
|
|
|
|
'Grafik',
|
|
|
|
style: TextStyle(fontWeight: FontWeight.bold),
|
|
|
|
),
|
|
|
|
const SizedBox(width: 40), // Platzhalter für zentrierte Ausrichtung
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
SliverToBoxAdapter( // Diagramm Anzeigen
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(10.0),
|
|
|
|
child: StackedColumnChart(
|
|
|
|
lowerValues: investedMoneyList,
|
|
|
|
upperValues: compoundInterestList,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
SliverToBoxAdapter( // Tabelle mit allen Werten anzeigen
|
|
|
|
child: Padding(
|
|
|
|
padding: const EdgeInsets.all(10.0),
|
|
|
|
child: Container(
|
|
|
|
decoration: BoxDecoration(
|
|
|
|
color: CupertinoColors.black,
|
|
|
|
borderRadius: BorderRadius.circular(5),
|
|
|
|
),
|
|
|
|
clipBehavior: Clip.antiAlias,
|
|
|
|
child: Table(
|
|
|
|
columnWidths: const {
|
|
|
|
0: FixedColumnWidth(60), // Spaltenbreite für die erste Spalte verringern
|
|
|
|
1: FlexColumnWidth(),
|
|
|
|
2: FlexColumnWidth(),
|
|
|
|
3: FlexColumnWidth(),
|
|
|
|
},
|
|
|
|
border: TableBorder.symmetric(
|
|
|
|
inside: const BorderSide(color: CupertinoColors.white, width: 1),
|
|
|
|
),
|
|
|
|
children: [
|
|
|
|
const TableRow(
|
|
|
|
decoration: BoxDecoration(color: CupertinoColors.darkBackgroundGray),
|
|
|
|
children: [
|
|
|
|
Padding(
|
|
|
|
padding: EdgeInsets.all(8.0),
|
|
|
|
child: Text(
|
|
|
|
'Jahr',
|
|
|
|
style: TextStyle(
|
|
|
|
color: CupertinoColors.white,
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
),
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
Padding(
|
|
|
|
padding: EdgeInsets.all(8.0),
|
|
|
|
child: Text(
|
|
|
|
'Einzahlungen',
|
|
|
|
style: TextStyle(
|
|
|
|
color: CupertinoColors.white,
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
),
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
Padding(
|
|
|
|
padding: EdgeInsets.all(8.0),
|
|
|
|
child: Text(
|
|
|
|
'Zinsen',
|
|
|
|
style: TextStyle(
|
|
|
|
color: CupertinoColors.white,
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
),
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
Padding(
|
|
|
|
padding: EdgeInsets.all(8.0),
|
|
|
|
child: Text(
|
|
|
|
'Endkapital',
|
|
|
|
style: TextStyle(
|
|
|
|
color: CupertinoColors.white,
|
|
|
|
fontWeight: FontWeight.bold,
|
|
|
|
),
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
for (int i = 0; i < investedMoneyList.length; i++)
|
|
|
|
TableRow(
|
|
|
|
children: [
|
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
child: Text(
|
|
|
|
'${i + 1}',
|
|
|
|
style: const TextStyle(color: CupertinoColors.white),
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
child: Text(
|
|
|
|
'€${investedMoneyList[i]}',
|
|
|
|
style: const TextStyle(color: CupertinoColors.white),
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
child: Text(
|
|
|
|
'€${compoundInterestList[i]}',
|
|
|
|
style: const TextStyle(color: CupertinoColors.white),
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
Padding(
|
|
|
|
padding: const EdgeInsets.all(8.0),
|
|
|
|
child: Text(
|
|
|
|
'€${compoundInterestList[i] + investedMoneyList[i]}',
|
|
|
|
style: const TextStyle(color: CupertinoColors.white),
|
|
|
|
textAlign: TextAlign.center,
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
),
|
|
|
|
],
|
|
|
|
),
|
|
|
|
);
|
|
|
|
}
|