Changed features
parent
b791a4b69f
commit
473db9335e
Binary file not shown.
After Width: | Height: | Size: 300 KiB |
Binary file not shown.
After Width: | Height: | Size: 1.6 MiB |
|
@ -0,0 +1,35 @@
|
|||
import 'package:flutter_application_1/enums.dart';
|
||||
|
||||
// Berechnet das investierte Geld über eine bestimmte Zeit
|
||||
double calculateInvestedMoney(double initialCapital, double monthlySavingsRate, double time, List<double> investedMoneyList) {
|
||||
double investedMoney = initialCapital;
|
||||
investedMoneyList.clear();
|
||||
for (int i = 0; i < time; i++) {
|
||||
investedMoney += monthlySavingsRate * 12; // Jährliche Sparrate hinzufügen
|
||||
investedMoney = investedMoney.roundToDouble();
|
||||
investedMoneyList.add(investedMoney); // Investierten Betrag zur Liste hinzufügen
|
||||
}
|
||||
return investedMoney;
|
||||
}
|
||||
|
||||
// Berechnet den Zinseszins über eine bestimmte Zeit.
|
||||
double calculateCompoundInterest(double initialCapital, double monthlySavingsRate, double interestRate, double time, PayoutInterval payoutInterval, List<double> investedMoneyList, List<double> compoundInterestList) {
|
||||
double compoundInterest = initialCapital;
|
||||
compoundInterestList.clear();
|
||||
if (payoutInterval == PayoutInterval.yearly) { // Berechnung für jährliche Auszahlung
|
||||
for (int i = 0; i < time; i++) {
|
||||
compoundInterest += compoundInterest * (interestRate / 100) + monthlySavingsRate * 12; // Zinsen und jährliche Sparrate hinzufügen
|
||||
compoundInterest = compoundInterest.roundToDouble();
|
||||
compoundInterestList.add(compoundInterest - investedMoneyList[i]); // Zinseszins zur Liste hinzufügen
|
||||
}
|
||||
} else { // Berechnung für monatliche Auszahlung
|
||||
for (int i = 0; i < time; i++) {
|
||||
for (int j = 0; j < 12; j++) {
|
||||
compoundInterest += compoundInterest * ((interestRate / 100) / 12) + monthlySavingsRate; // Monatliche Zinsen und Sparrate hinzufügen
|
||||
compoundInterest = compoundInterest.roundToDouble();
|
||||
}
|
||||
compoundInterestList.add(compoundInterest - investedMoneyList[i]); // Zinseszins zur Liste hinzufügen
|
||||
}
|
||||
}
|
||||
return compoundInterest; // Gesamtkapital nach Zinseszinsberechnung zurückgeben
|
||||
}
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter_application_1/calculator.dart';
|
||||
import 'package:flutter_application_1/enums.dart';
|
||||
import 'package:flutter_application_1/translations.dart';
|
||||
import 'package:flutter_application_1/utils.dart';
|
||||
|
@ -122,17 +123,15 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
_timeController.text = '10';
|
||||
}
|
||||
|
||||
|
||||
double _initialCapital = 0.0; // Anfangskapital
|
||||
double _monthlySavingsRate = 0.0; // Monatliche Sparrate
|
||||
double _interestRate = 0.0; // Jährlicher Zinssatz
|
||||
double _time = 0.0; // Anlagezeitraum in Jahren
|
||||
double _investedMoney = 0.0; // Investiertes Geld ohne Zinsen
|
||||
final List<double> _investedMoneyList = []; // Investiertes Geld ohne Zinsen (pro Jahr)
|
||||
PayoutInterval _payoutInterval = PayoutInterval.yearly; // Standardwert für das Ausschüttungsintervall
|
||||
double _compoundInterest = 0.0; // Investiertes Geld mit Zinsen
|
||||
final List<double> _compoundInterestList = []; // Investiertes Geld mit Zinsen (pro Jahr)
|
||||
bool _calculationPerformed = false;
|
||||
double _initialCapital = 0.0; // Das anfängliche Kapital
|
||||
double _monthlySavingsRate = 0.0; // Der monatliche Sparbetrag
|
||||
double _interestRate = 0.0; // Der jährliche Zinssatz
|
||||
double _time = 0.0; // Der Anlagezeitraum in Jahren
|
||||
double _investedMoney = 0.0; // Das investierte Geld
|
||||
final List<double> _investedMoneyList = []; // Liste, die das investierte Geld pro Jahr speichert
|
||||
PayoutInterval _payoutInterval = PayoutInterval.yearly; // Das Auszahlungsintervall (jährlich oder monatlich)
|
||||
double _compoundInterest = 0.0; // Der Zinseszins
|
||||
final List<double> _compoundInterestList = []; // Liste, die den Zinseszins pro Jahr speichert
|
||||
|
||||
// Methoden zum Festlegen der Werte aus den Eingabefeldern
|
||||
void setInitialCapital() {
|
||||
|
@ -159,44 +158,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
});
|
||||
}
|
||||
|
||||
// Methode zum Berechnen des investierten Geldes
|
||||
void _calculateInvestedMoney() {
|
||||
setState(() {
|
||||
_investedMoneyList.clear();
|
||||
_investedMoney = _initialCapital;
|
||||
for (int i = 0; i < _time; i++) {
|
||||
_investedMoney += _monthlySavingsRate * 12;
|
||||
_investedMoney = _investedMoney.roundToDouble();
|
||||
_investedMoneyList.add(_investedMoney);
|
||||
}
|
||||
_calculationPerformed = true;
|
||||
});
|
||||
}
|
||||
|
||||
// Methode zum Berechnen der Zinsen
|
||||
void _calculateCompoundInterest() {
|
||||
setState(() {
|
||||
_compoundInterestList.clear();
|
||||
_compoundInterest = _initialCapital;
|
||||
if(_payoutInterval == PayoutInterval.yearly){
|
||||
for(int i = 0; i < _time; i++){
|
||||
_compoundInterest += _compoundInterest * (_interestRate / 100) + _monthlySavingsRate * 12;
|
||||
_compoundInterest = _compoundInterest.roundToDouble();
|
||||
_compoundInterestList.add(_compoundInterest - _investedMoneyList[i]);
|
||||
}
|
||||
}
|
||||
else{
|
||||
for(int i = 0; i < _time; i++){
|
||||
for(int j = 0; j < 12; j++){
|
||||
_compoundInterest += _compoundInterest * ((_interestRate / 100) / 12) + _monthlySavingsRate;
|
||||
_compoundInterest = _compoundInterest.roundToDouble();
|
||||
}
|
||||
_compoundInterestList.add(_compoundInterest - _investedMoneyList[i]);
|
||||
}
|
||||
}
|
||||
_calculationPerformed = true;
|
||||
});
|
||||
}
|
||||
bool calculationPerformed = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
|
@ -227,12 +189,18 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
setMonthlySavingsRate();
|
||||
setInterestRate();
|
||||
setTime();
|
||||
_calculateInvestedMoney();
|
||||
_calculateCompoundInterest();
|
||||
_investedMoney = calculateInvestedMoney(_initialCapital, _monthlySavingsRate, _time, _investedMoneyList);
|
||||
_compoundInterest = calculateCompoundInterest(_initialCapital, _monthlySavingsRate, _interestRate, _time, _payoutInterval, _investedMoneyList, _compoundInterestList);
|
||||
calculationPerformed = true;
|
||||
},
|
||||
style: ButtonStyle(
|
||||
backgroundColor: MaterialStateProperty.all<Color>(CupertinoColors.black),
|
||||
foregroundColor: MaterialStateProperty.all<Color>(CupertinoColors.white),
|
||||
shape: MaterialStateProperty.all<RoundedRectangleBorder>(
|
||||
RoundedRectangleBorder(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
),
|
||||
),
|
||||
),
|
||||
child: const Text(
|
||||
'Berechnen',
|
||||
|
@ -242,8 +210,8 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
if(_calculationPerformed)
|
||||
buildResultWidget('$_compoundInterest', '$_investedMoney', '$_time', '$_monthlySavingsRate', '$_interestRate', _payoutInterval, _investedMoneyList, _compoundInterestList),
|
||||
if (calculationPerformed)
|
||||
buildResultWidget(context, '$_compoundInterest', '$_investedMoney', '$_time', '$_monthlySavingsRate', '$_interestRate', _payoutInterval, _investedMoneyList, _compoundInterestList),
|
||||
],
|
||||
),
|
||||
)
|
||||
|
|
|
@ -1,10 +1,10 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||
|
||||
// Widget für ein gestapeltes Säulendiagramm
|
||||
// Widget zur Erstellung eines gestapelten Säulendiagramms
|
||||
class StackedColumnChart extends StatelessWidget {
|
||||
final List<double> lowerValues;
|
||||
final List<double> upperValues;
|
||||
final List<double> lowerValues; // Liste der unteren Werte für das Diagramm
|
||||
final List<double> upperValues; // Liste der oberen Werte für das Diagramm
|
||||
|
||||
const StackedColumnChart({
|
||||
super.key,
|
||||
|
@ -16,8 +16,8 @@ class StackedColumnChart extends StatelessWidget {
|
|||
Widget build(BuildContext context) {
|
||||
return SfCartesianChart(
|
||||
legend: const Legend(
|
||||
isVisible: true, // Legende anzeigen
|
||||
position: LegendPosition.top, // Legende unterhalb des Diagramms platzieren
|
||||
isVisible: true,
|
||||
position: LegendPosition.top,
|
||||
),
|
||||
primaryXAxis: const CategoryAxis(
|
||||
title: AxisTitle(text: 'Jahr'),
|
||||
|
@ -26,24 +26,24 @@ class StackedColumnChart extends StatelessWidget {
|
|||
title: AxisTitle(text: 'Euro'),
|
||||
),
|
||||
series: <CartesianSeries>[
|
||||
// Untere Teil der Säule
|
||||
// Serie für die Einzahlungen (untere Werte)
|
||||
StackedColumnSeries<SalesData, int>(
|
||||
dataSource: _getLowerChartData(),
|
||||
xValueMapper: (SalesData sales, _) => sales.year,
|
||||
yValueMapper: (SalesData sales, _) => sales.value,
|
||||
name: 'Einzahlungen',
|
||||
color: CupertinoColors.systemRed.highContrastColor,
|
||||
color: CupertinoColors.systemGrey.darkHighContrastColor,
|
||||
),
|
||||
// Obere Teil der Säule
|
||||
// Serie für die Zinsen (obere Werte)
|
||||
StackedColumnSeries<SalesData, int>(
|
||||
dataSource: _getUpperChartData(),
|
||||
xValueMapper: (SalesData sales, _) => sales.year,
|
||||
yValueMapper: (SalesData sales, _) => sales.value,
|
||||
name: 'Zinsen',
|
||||
color: CupertinoColors.systemBlue.highContrastColor,
|
||||
color: CupertinoColors.systemGreen.highContrastColor,
|
||||
),
|
||||
],
|
||||
// Trackball für Hover-Interaktion
|
||||
// Konfiguration für die Interaktivität des Diagramms
|
||||
trackballBehavior: TrackballBehavior(
|
||||
enable: true,
|
||||
tooltipSettings: const InteractiveTooltip(enable: true),
|
||||
|
@ -53,7 +53,7 @@ class StackedColumnChart extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
// Methode zum Erstellen der Daten für den unteren Teil der Säule (Investiertes Geld)
|
||||
// Methode zur Erstellung der Daten für die untere Serie (Einzahlungen)
|
||||
List<SalesData> _getLowerChartData() {
|
||||
List<SalesData> chartData = [];
|
||||
for (int i = 0; i < lowerValues.length; i++) {
|
||||
|
@ -61,7 +61,8 @@ class StackedColumnChart extends StatelessWidget {
|
|||
}
|
||||
return chartData;
|
||||
}
|
||||
// Methode zum Erstellen der Daten für den oberen Teil der Säule (Investiertes Geld mit Zinsen)
|
||||
|
||||
// Methode zur Erstellung der Daten für die obere Serie (Zinsen)
|
||||
List<SalesData> _getUpperChartData() {
|
||||
List<SalesData> chartData = [];
|
||||
for (int i = 0; i < upperValues.length; i++) {
|
||||
|
@ -71,6 +72,7 @@ class StackedColumnChart extends StatelessWidget {
|
|||
}
|
||||
}
|
||||
|
||||
// Klasse zur Modellierung der Datenpunkte im Diagramm
|
||||
class SalesData {
|
||||
final int year;
|
||||
final double value;
|
||||
|
|
|
@ -0,0 +1,37 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
class CustomImageButton extends StatelessWidget {
|
||||
final VoidCallback onPressed;
|
||||
final Widget child;
|
||||
final String backgroundImage;
|
||||
|
||||
const CustomImageButton({
|
||||
super.key,
|
||||
required this.onPressed,
|
||||
required this.child,
|
||||
required this.backgroundImage,
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Material(
|
||||
color: Colors.transparent,
|
||||
child: InkWell(
|
||||
onTap: onPressed,
|
||||
child: Container(
|
||||
height: 150,
|
||||
decoration: BoxDecoration(
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
image: DecorationImage(
|
||||
image: AssetImage(backgroundImage),
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
),
|
||||
child: Center(
|
||||
child: child,
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,72 +0,0 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// Widget für eine erweiterbare Box
|
||||
class ExpandableBox extends StatefulWidget {
|
||||
final String headerText;
|
||||
final Widget expandedContent;
|
||||
|
||||
const ExpandableBox({super.key, required this.headerText, required this.expandedContent});
|
||||
|
||||
@override
|
||||
// ignore: library_private_types_in_public_api
|
||||
_ExpandableBoxState createState() => _ExpandableBoxState();
|
||||
}
|
||||
|
||||
class _ExpandableBoxState extends State<ExpandableBox> {
|
||||
bool _isExpanded = false;
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
// GestureDetector zum Erfassen von Klicks zum Erweitern oder Verkleinern der Box
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
_isExpanded = !_isExpanded;
|
||||
});
|
||||
},
|
||||
child: Container(
|
||||
decoration: BoxDecoration(
|
||||
color: CupertinoColors.extraLightBackgroundGray,
|
||||
borderRadius: _isExpanded ? const BorderRadius.only(topLeft: Radius.circular(5), topRight: Radius.circular(5),) : BorderRadius.circular(5),
|
||||
),
|
||||
child: Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 16.0),
|
||||
child: Text(
|
||||
widget.headerText,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold
|
||||
),
|
||||
),
|
||||
),
|
||||
Icon(
|
||||
_isExpanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down,
|
||||
size: 30,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
if (_isExpanded)
|
||||
Container(
|
||||
decoration: const BoxDecoration(
|
||||
color: CupertinoColors.extraLightBackgroundGray,
|
||||
borderRadius: BorderRadius.only(
|
||||
bottomLeft: Radius.circular(5),
|
||||
bottomRight: Radius.circular(5),
|
||||
),
|
||||
),
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(20), // Hier kannst du den gewünschten Padding-Wert festlegen
|
||||
child: widget.expandedContent,
|
||||
),
|
||||
)
|
||||
],
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// Funktion zum Erstellen eines Eingabe-Widgets
|
||||
// Erstellt ein Widget für die Eingabe mit einem Label, einem Texteingabefeld, einer Validierungsanzeige und einem Tooltip
|
||||
Widget buildInputWidget(String label, TextEditingController controller, FocusNode focusNode, bool isValid, String suffixText, String tooltipText) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
@ -9,11 +9,11 @@ Widget buildInputWidget(String label, TextEditingController controller, FocusNod
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// Zeile für das Label und den Tooltip
|
||||
Row(
|
||||
children: [
|
||||
Row(
|
||||
children: [
|
||||
// Label für das Eingabefeld
|
||||
Text(
|
||||
label,
|
||||
style: const TextStyle(
|
||||
|
@ -22,6 +22,7 @@ Widget buildInputWidget(String label, TextEditingController controller, FocusNod
|
|||
),
|
||||
),
|
||||
const SizedBox(width: 5),
|
||||
// Tooltip-Icon mit Erklärungstext
|
||||
Tooltip(
|
||||
message: tooltipText,
|
||||
triggerMode: TooltipTriggerMode.tap,
|
||||
|
@ -39,6 +40,7 @@ Widget buildInputWidget(String label, TextEditingController controller, FocusNod
|
|||
),
|
||||
],
|
||||
),
|
||||
// Icon zur Anzeige der Validierung (grün für gültig, rot für ungültig)
|
||||
isValid
|
||||
? const Icon(
|
||||
CupertinoIcons.check_mark_circled_solid,
|
||||
|
@ -53,7 +55,7 @@ Widget buildInputWidget(String label, TextEditingController controller, FocusNod
|
|||
],
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
// Textfeld für die Eingabe
|
||||
// Texteingabefeld mit Suffix-Text
|
||||
CupertinoTextField(
|
||||
controller: controller,
|
||||
focusNode: focusNode,
|
||||
|
|
|
@ -3,27 +3,28 @@ import 'package:flutter/material.dart';
|
|||
import 'package:flutter_application_1/enums.dart';
|
||||
import 'package:flutter_application_1/translations.dart';
|
||||
|
||||
// Widget zur Auswahl des Ausschüttungsintervalls
|
||||
class IntervalWidget extends StatefulWidget {
|
||||
final String selectedInterval;
|
||||
final Function(String) onChanged;
|
||||
|
||||
const IntervalWidget({super.key, required this.selectedInterval, required this.onChanged});
|
||||
const IntervalWidget({
|
||||
super.key,
|
||||
required this.selectedInterval,
|
||||
required this.onChanged
|
||||
});
|
||||
|
||||
@override
|
||||
// ignore: library_private_types_in_public_api
|
||||
_IntervalWidgetState createState() => _IntervalWidgetState();
|
||||
IntervalWidgetState createState() => IntervalWidgetState();
|
||||
}
|
||||
|
||||
class _IntervalWidgetState extends State<IntervalWidget> {
|
||||
bool isExpanded = false;
|
||||
class IntervalWidgetState extends State<IntervalWidget> {
|
||||
bool isExpanded = false; // Zustand, ob das Intervall-Auswahlfenster erweitert ist
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Überschrift für das Dropdown-Menü
|
||||
const Row(
|
||||
children: [
|
||||
Text(
|
||||
|
@ -34,6 +35,7 @@ class _IntervalWidgetState extends State<IntervalWidget> {
|
|||
),
|
||||
),
|
||||
SizedBox(width: 5),
|
||||
// Tooltip mit Erklärung zum Ausschüttungsintervall
|
||||
Tooltip(
|
||||
message: 'Das Ausschüttungsintervall bezieht sich darauf, wie oft die Erträge aus Ihrer Investition ausgeschüttet werden.',
|
||||
triggerMode: TooltipTriggerMode.tap,
|
||||
|
@ -49,19 +51,19 @@ class _IntervalWidgetState extends State<IntervalWidget> {
|
|||
),
|
||||
]
|
||||
),
|
||||
// Dropdown-Menü
|
||||
CupertinoTextField(
|
||||
placeholder: 'Ausschüttungsintervall auswählen',
|
||||
readOnly: true,
|
||||
onTap: () {
|
||||
// Öffnet das ModalBottomSheet zur Auswahl des Ausschüttungsintervalls
|
||||
showModalBottomSheet(
|
||||
context: context,
|
||||
backgroundColor: CupertinoColors.white,
|
||||
backgroundColor: CupertinoColors.black,
|
||||
builder: (BuildContext context) {
|
||||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// Liste von Auswahlmöglichkeiten
|
||||
// ListTile für jährliches Ausschüttungsintervall
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: ListTile(
|
||||
|
@ -69,17 +71,17 @@ class _IntervalWidgetState extends State<IntervalWidget> {
|
|||
translateInterval(PayoutInterval.yearly),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: CupertinoColors.white,
|
||||
),
|
||||
),
|
||||
hoverColor: Colors.transparent,
|
||||
trailing: widget.selectedInterval == translateInterval(PayoutInterval.yearly) ? const Icon(CupertinoIcons.checkmark_alt) : null,
|
||||
trailing: widget.selectedInterval == translateInterval(PayoutInterval.yearly) ? const Icon(CupertinoIcons.checkmark_alt, color: CupertinoColors.white,) : null,
|
||||
onTap: () {
|
||||
// Auswahl des jährlichen Intervalls und Schließen des Bottom Sheets
|
||||
widget.onChanged(translateInterval(PayoutInterval.yearly));
|
||||
Navigator.pop(context);
|
||||
},
|
||||
),
|
||||
),
|
||||
// ListTile für monatliches Ausschüttungsintervall
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: ListTile(
|
||||
|
@ -87,12 +89,11 @@ class _IntervalWidgetState extends State<IntervalWidget> {
|
|||
translateInterval(PayoutInterval.monthly),
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
color: CupertinoColors.white,
|
||||
),
|
||||
),
|
||||
hoverColor: Colors.transparent,
|
||||
trailing: widget.selectedInterval == translateInterval(PayoutInterval.monthly) ? const Icon(CupertinoIcons.checkmark_alt) : null,
|
||||
trailing: widget.selectedInterval == translateInterval(PayoutInterval.monthly) ? const Icon(CupertinoIcons.checkmark_alt, color: CupertinoColors.white,) : null,
|
||||
onTap: () {
|
||||
// Auswahl des monatlichen Intervalls und Schließen des Bottom Sheets
|
||||
widget.onChanged(translateInterval(PayoutInterval.monthly));
|
||||
Navigator.pop(context);
|
||||
},
|
||||
|
@ -103,18 +104,19 @@ class _IntervalWidgetState extends State<IntervalWidget> {
|
|||
},
|
||||
).then((value) {
|
||||
setState(() {
|
||||
isExpanded = false;
|
||||
isExpanded = false; // Setzt den Zustand auf nicht erweitert zurück, wenn das Modal geschlossen wird
|
||||
});
|
||||
});
|
||||
setState(() {
|
||||
isExpanded = true;
|
||||
isExpanded = true; // Setzt den Zustand auf erweitert
|
||||
});
|
||||
},
|
||||
// Suffix-Icon, das den Zustand anzeigt (erweitert oder nicht)
|
||||
suffix: Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 5.0),
|
||||
child: Icon(isExpanded ? Icons.keyboard_arrow_up : Icons.keyboard_arrow_down),
|
||||
),
|
||||
controller: TextEditingController(text: widget.selectedInterval),
|
||||
controller: TextEditingController(text: widget.selectedInterval), // Setzt den Text des Textfeldes auf das ausgewählte Intervall
|
||||
decoration: BoxDecoration(
|
||||
color: CupertinoColors.extraLightBackgroundGray,
|
||||
borderRadius: BorderRadius.circular(5),
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
// Erstellt eine Zeitleiste für Meilensteine
|
||||
import 'package:flutter/cupertino.dart';
|
||||
|
||||
Widget buildMilestoneTimeline(List<Map<String, dynamic>> milestones, double totalInterest) {
|
||||
return SizedBox(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: List.generate(milestones.length, (index) {
|
||||
double milestoneValue = milestones[index]['value'];
|
||||
String milestoneEmoji = milestones[index]['emoji'];
|
||||
String milestoneText = milestones[index]['text'];
|
||||
bool milestoneReached = totalInterest >= milestoneValue; // Überprüfen, ob Meilenstein erreicht wurde
|
||||
return Column(
|
||||
children: [
|
||||
if (index > 0)
|
||||
Container(
|
||||
height: 25,
|
||||
width: 2,
|
||||
color: milestoneReached ? CupertinoColors.systemGreen : CupertinoColors.black, // Linie zwischen Meilensteinen
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
milestoneEmoji,
|
||||
style: const TextStyle(fontSize: 20), // Emoji für Meilenstein
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
milestoneText,
|
||||
textAlign: TextAlign.center,
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Icon(
|
||||
milestoneReached ? CupertinoIcons.check_mark_circled_solid : CupertinoIcons.circle_fill,
|
||||
size: 20,
|
||||
color: milestoneReached ? CupertinoColors.systemGreen : CupertinoColors.black, // Icon, das den Status des Meilensteins anzeigt
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
|
@ -1,44 +1,79 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_application_1/enums.dart';
|
||||
import 'package:flutter_application_1/translations.dart';
|
||||
import 'package:flutter_application_1/widgets/expandable_widget.dart';
|
||||
import 'package:flutter_application_1/widgets/second_page_widget.dart';
|
||||
import 'package:flutter_application_1/widgets/custom_image_button_widget.dart';
|
||||
import 'package:flutter_application_1/widgets/chart_widget.dart';
|
||||
import 'package:flutter_application_1/widgets/milestone_timeline_widget.dart';
|
||||
|
||||
// Erstellt das Widget für das Ergebnis der Berechnungen
|
||||
Widget buildResultWidget(String compoundInterest, String investedMoney, String time, String monthlySavingsRate, String interestRate, PayoutInterval payoutInterval, List<double> investedMoneyList, List<double> compoundInterestList) {
|
||||
// Liste von Meilensteinen mit Werten, Bildern und Texten.
|
||||
// Erstellt ein Widget, das die Berechnungsergebnisse anzeigt
|
||||
Widget buildResultWidget(BuildContext context, String compoundInterest, String investedMoney, String time, String monthlySavingsRate, String interestRate, PayoutInterval payoutInterval, List<double> investedMoneyList, List<double> compoundInterestList) {
|
||||
// Liste von Meilensteinen mit Werten, Emojis und Beschreibungen
|
||||
List<Map<String, dynamic>> milestoneList = [
|
||||
{'value': 1329.0, 'emoji': '📱', 'text': 'iPhone 15 Pro Max\nPreis: 1329€'},
|
||||
{'value': 3071.0, 'emoji': '🚲', 'text': 'Flyer Gotour6 3.40\nPreis: 3071€'},
|
||||
{'value': 248157.0, 'emoji': '🏎️', 'text': 'Porsche 992 GT3 RS\nPreis: 248157€'},
|
||||
{'value': 450000.0, 'emoji': '🏡', 'text': '150qm Einfamilienhaus\nPreis: ca. 450000€'},
|
||||
{'value': 700.0, 'emoji': '📱', 'text': 'Smartphone\nPreis: 700€'},
|
||||
{'value': 3250.0, 'emoji': '🚲', 'text': 'eBike\nPreis: 3250€'},
|
||||
{'value': 20000.0, 'emoji': '🌎', 'text': 'Weltreise\nPreis: 20000€'},
|
||||
{'value': 100000.0, 'emoji': '🏎️', 'text': 'Sportwagen\nPreis: 100000€'},
|
||||
{'value': 350000.0, 'emoji': '🏡', 'text': '150qm Einfamilienhaus\nPreis: 350000€'},
|
||||
];
|
||||
|
||||
return Column(
|
||||
children: <Widget>[
|
||||
CustomImageButton(
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SecondPage(
|
||||
title: 'Grafik',
|
||||
widgetToShow: StackedColumnChart(
|
||||
lowerValues: investedMoneyList,
|
||||
upperValues: compoundInterestList,
|
||||
)
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
backgroundImage: 'assets/images/button_bg1.jpg',
|
||||
child: const Text(
|
||||
'Grafik',
|
||||
style: TextStyle(color: CupertinoColors.white, fontSize: 20),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
CustomImageButton(
|
||||
onPressed: () {
|
||||
Navigator.push(
|
||||
context,
|
||||
MaterialPageRoute(
|
||||
builder: (context) => SecondPage(
|
||||
title: 'Meilensteine',
|
||||
widgetToShow: buildMilestoneTimeline(milestoneList, double.parse(compoundInterest) - double.parse(investedMoney))
|
||||
),
|
||||
),
|
||||
);
|
||||
},
|
||||
backgroundImage: 'assets/images/button_bg2.jpg',
|
||||
child: const Text(
|
||||
'Meilensteine',
|
||||
style: TextStyle(color: CupertinoColors.white, fontSize: 20),
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
_buildResultRow('Endkapital:', '$compoundInterest€'),
|
||||
_buildResultRow('Einzahlungen:', '$investedMoney€'),
|
||||
_buildResultRow('Erhaltene Zinsen:', '${double.parse(compoundInterest) - double.parse(investedMoney)}€'),
|
||||
const SizedBox(height: 20),
|
||||
const SizedBox(height: 10),
|
||||
Text(
|
||||
'Wenn du über einen Zeitraum von $time Jahren ${translateInterval(payoutInterval)} $monthlySavingsRate€ mit einem Zinssatz von $interestRate% investierst, erreichst du am Ende ein Endkapital von $compoundInterest€. Dieses setzt sich aus Einzahlungen von $investedMoney€ und Zinsen bzw. Kapitalerträgen in Höhe von ${double.parse(compoundInterest) - double.parse(investedMoney)}€ zusammen.'
|
||||
),
|
||||
const SizedBox(height: 20),
|
||||
ExpandableBox(
|
||||
headerText: 'Grafik',
|
||||
expandedContent: StackedColumnChart(
|
||||
lowerValues: investedMoneyList,
|
||||
upperValues: compoundInterestList,
|
||||
),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
ExpandableBox(
|
||||
headerText: 'Meilensteine',
|
||||
expandedContent: buildMilestoneTimeline(milestoneList, double.parse(compoundInterest) - double.parse(investedMoney)),
|
||||
),
|
||||
],
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
// Erstellt eine Zeile mit einem Label und einem Wert
|
||||
Widget _buildResultRow(String label, String value) {
|
||||
return Padding(
|
||||
padding: const EdgeInsets.symmetric(horizontal: 20),
|
||||
|
@ -68,62 +103,3 @@ Widget _buildResultRow(String label, String value) {
|
|||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
|
||||
// Erstellt die Meilenstein-Timeline.
|
||||
Widget buildMilestoneTimeline(List<Map<String, dynamic>> milestones, double totalInterest) {
|
||||
return SizedBox(
|
||||
child: Center(
|
||||
child: Column(
|
||||
mainAxisAlignment: MainAxisAlignment.center,
|
||||
children: List.generate(milestones.length, (index) {
|
||||
// Werte aus dem Meilenstein-Objekt extrahieren
|
||||
double milestoneValue = milestones[index]['value'];
|
||||
String milestoneEmoji = milestones[index]['emoji'];
|
||||
String milestoneText = milestones[index]['text'];
|
||||
bool milestoneReached = totalInterest >= milestoneValue;
|
||||
return Column(
|
||||
children: [
|
||||
if (index > 0) // Zeigt eine vertikale Linie an zwischen den Meilensteinen
|
||||
Container(
|
||||
height: 50,
|
||||
width: 2,
|
||||
color: milestoneReached ? CupertinoColors.systemGreen : CupertinoColors.black,
|
||||
),
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Column(
|
||||
children: [
|
||||
Text(
|
||||
milestoneEmoji,
|
||||
style: const TextStyle(fontSize: 25),
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
milestoneText,
|
||||
textAlign: TextAlign.center,
|
||||
style: const TextStyle(
|
||||
fontWeight: FontWeight.bold,
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
// Zeigt ein Häkchen oder einen Kreis je nach Erreichen des Meilensteins an
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Icon(
|
||||
milestoneReached ? CupertinoIcons.check_mark_circled_solid : CupertinoIcons.circle_fill,
|
||||
size: 20,
|
||||
color: milestoneReached ? CupertinoColors.systemGreen : CupertinoColors.black,
|
||||
),
|
||||
),
|
||||
],
|
||||
);
|
||||
}),
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,50 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
class SecondPage extends StatelessWidget {
|
||||
final String title;
|
||||
final Widget widgetToShow;
|
||||
|
||||
const SecondPage({
|
||||
super.key,
|
||||
required this.title,
|
||||
required this.widgetToShow
|
||||
});
|
||||
|
||||
@override
|
||||
Widget build(BuildContext context) {
|
||||
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);
|
||||
},
|
||||
),
|
||||
Text(
|
||||
title,
|
||||
style: const TextStyle(fontWeight: FontWeight.bold),
|
||||
),
|
||||
const SizedBox(width: 40), // Platzhalter für zentrierte Ausrichtung
|
||||
],
|
||||
),
|
||||
),
|
||||
),
|
||||
SliverToBoxAdapter(
|
||||
child: Padding(
|
||||
padding: const EdgeInsets.all(10.0),
|
||||
child: widgetToShow, // Anzeigen des mitgegebenen Widgets
|
||||
),
|
||||
),
|
||||
],
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
|
@ -60,8 +60,9 @@ flutter:
|
|||
uses-material-design: true
|
||||
|
||||
# To add assets to your application, add an assets section, like this:
|
||||
# assets:
|
||||
# - assets/images/
|
||||
assets:
|
||||
- assets/images/button_bg1.jpg
|
||||
- assets/images/button_bg2.jpg
|
||||
|
||||
# An image asset can refer to one or more resolution-specific "variants", see
|
||||
# https://flutter.dev/assets-and-images/#resolution-aware
|
||||
|
|
Loading…
Reference in New Issue