Added code comments
parent
7370acc486
commit
3c1011b83a
|
@ -37,23 +37,27 @@ class MyHomePage extends StatefulWidget {
|
|||
}
|
||||
|
||||
class _MyHomePageState extends State<MyHomePage> {
|
||||
// Controller und Fokus-Knoten für die Eingabefelder
|
||||
final TextEditingController _initialCapitalController = TextEditingController();
|
||||
final TextEditingController _monthlySavingsRateController = TextEditingController();
|
||||
final TextEditingController _interestRateController = TextEditingController();
|
||||
final TextEditingController _timeController = TextEditingController();
|
||||
bool _isInitialCapitalEntered = false;
|
||||
bool _isMonthlySavingsRateEntered = false;
|
||||
bool _isInterestRateEntered = false;
|
||||
bool _isTimeEntered = false;
|
||||
final FocusNode _initialCapitalFocusNode = FocusNode();
|
||||
final FocusNode _monthlySavingsRateFocusNode = FocusNode();
|
||||
final FocusNode _interestRateFocusNode = FocusNode();
|
||||
final FocusNode _timeFocusNode = FocusNode();
|
||||
|
||||
// Zustandsvariablen für die Validierung der Eingaben
|
||||
bool _isInitialCapitalEntered = false;
|
||||
bool _isMonthlySavingsRateEntered = false;
|
||||
bool _isInterestRateEntered = false;
|
||||
bool _isTimeEntered = false;
|
||||
|
||||
@override
|
||||
void initState() {
|
||||
super.initState();
|
||||
|
||||
// Listener für die Eingabefelder, um die Validierung durchzuführen und Standardwerte wiederherzustellen
|
||||
_initialCapitalController.addListener(() {
|
||||
setState(() {
|
||||
_isInitialCapitalEntered = _initialCapitalController.text.isNotEmpty &&
|
||||
|
@ -86,6 +90,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
});
|
||||
});
|
||||
|
||||
// Listener für die Fokus-Knoten, um die Eingabe zu runden, wenn der Fokus verloren geht
|
||||
_initialCapitalFocusNode.addListener(() {
|
||||
if (!_initialCapitalFocusNode.hasFocus) {
|
||||
roundToInteger(_initialCapitalController);
|
||||
|
@ -110,10 +115,11 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
}
|
||||
});
|
||||
|
||||
_initialCapitalController.text = '1000'; // Beispielwert für Anfangskapital
|
||||
_monthlySavingsRateController.text = '50'; // Beispielwert für monatliche Sparrate
|
||||
_interestRateController.text = '5'; // Beispielwert für jährlichen Zinssatz
|
||||
_timeController.text = '10'; // Beispielwert für Anlagezeitraum
|
||||
// Setzen von Beispielwerten für die Eingabefelder
|
||||
_initialCapitalController.text = '1000';
|
||||
_monthlySavingsRateController.text = '50';
|
||||
_interestRateController.text = '5';
|
||||
_timeController.text = '10';
|
||||
}
|
||||
|
||||
|
||||
|
@ -122,12 +128,13 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
double _interestRate = 0.0; // Jährlicher Zinssatz
|
||||
double _time = 0.0; // Anlagezeitraum in Jahren
|
||||
double _investedMoney = 0.0; // Investiertes Geld ohne Zinsen
|
||||
List<double> _investedMoneyList = []; // Investiertes Geld ohne Zinsen (pro Jahr)
|
||||
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
|
||||
List<double> _compoundInterestList = []; // Investiertes Geld mit Zinsen (pro Jahr)
|
||||
final List<double> _compoundInterestList = []; // Investiertes Geld mit Zinsen (pro Jahr)
|
||||
bool _calculationPerformed = false;
|
||||
|
||||
// Methoden zum Festlegen der Werte aus den Eingabefeldern
|
||||
void setInitialCapital() {
|
||||
setState(() {
|
||||
_initialCapital = double.parse(_initialCapitalController.text);
|
||||
|
@ -152,6 +159,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
});
|
||||
}
|
||||
|
||||
// Methode zum Berechnen des investierten Geldes
|
||||
void _calculateInvestedMoney() {
|
||||
setState(() {
|
||||
_investedMoneyList.clear();
|
||||
|
@ -165,6 +173,7 @@ class _MyHomePageState extends State<MyHomePage> {
|
|||
});
|
||||
}
|
||||
|
||||
// Methode zum Berechnen der Zinsen
|
||||
void _calculateCompoundInterest() {
|
||||
setState(() {
|
||||
_compoundInterestList.clear();
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
import 'package:flutter/material.dart';
|
||||
|
||||
// Rundet den Wert im Textfeld-Controller auf die nächste ganze Zahl
|
||||
void roundToInteger(TextEditingController controller) {
|
||||
double? parsedValue = double.tryParse(controller.text.replaceAll(',', '.'));
|
||||
if (parsedValue != null) {
|
||||
|
@ -8,10 +9,12 @@ void roundToInteger(TextEditingController controller) {
|
|||
}
|
||||
}
|
||||
|
||||
// Überprüft, ob der gegebene Wert eine numerische Darstellung ist
|
||||
bool isNumeric(String value) {
|
||||
return double.tryParse(value.replaceAll(',', '.')) != null;
|
||||
return double.tryParse(value.replaceAll(',', '.')) != null; // Wert in einen double umwandeln
|
||||
}
|
||||
|
||||
// Setzt den Standardwert 0 für den Controller, wenn das Feld leer ist
|
||||
void restoreDefaultValuesIfEmpty(TextEditingController controller) {
|
||||
if (controller.text.isEmpty) {
|
||||
controller.text = '0';
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:syncfusion_flutter_charts/charts.dart';
|
||||
|
||||
// Widget für ein gestapeltes Säulendiagramm
|
||||
class StackedColumnChart extends StatelessWidget {
|
||||
final List<double> lowerValues;
|
||||
final List<double> upperValues;
|
||||
|
@ -21,12 +22,14 @@ class StackedColumnChart extends StatelessWidget {
|
|||
title: AxisTitle(text: 'Euro'),
|
||||
),
|
||||
series: <CartesianSeries>[
|
||||
// Untere Teil der Säule
|
||||
StackedColumnSeries<SalesData, int>(
|
||||
dataSource: _getLowerChartData(),
|
||||
xValueMapper: (SalesData sales, _) => sales.year,
|
||||
yValueMapper: (SalesData sales, _) => sales.value,
|
||||
color: CupertinoColors.systemRed.highContrastColor,
|
||||
),
|
||||
// Obere Teil der Säule
|
||||
StackedColumnSeries<SalesData, int>(
|
||||
dataSource: _getUpperChartData(),
|
||||
xValueMapper: (SalesData sales, _) => sales.year,
|
||||
|
@ -37,6 +40,7 @@ class StackedColumnChart extends StatelessWidget {
|
|||
);
|
||||
}
|
||||
|
||||
// Methode zum Erstellen der Daten für den unteren Teil der Säule (Investiertes Geld)
|
||||
List<SalesData> _getLowerChartData() {
|
||||
List<SalesData> chartData = [];
|
||||
for (int i = 0; i < lowerValues.length; i++) {
|
||||
|
@ -44,7 +48,7 @@ class StackedColumnChart extends StatelessWidget {
|
|||
}
|
||||
return chartData;
|
||||
}
|
||||
|
||||
// Methode zum Erstellen der Daten für den oberen Teil der Säule (Investiertes Geld mit Zinsen)
|
||||
List<SalesData> _getUpperChartData() {
|
||||
List<SalesData> chartData = [];
|
||||
for (int i = 0; i < upperValues.length; i++) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
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;
|
||||
|
@ -19,6 +20,7 @@ class _ExpandableBoxState extends State<ExpandableBox> {
|
|||
Widget build(BuildContext context) {
|
||||
return Column(
|
||||
children: [
|
||||
// GestureDetector zum Erfassen von Klicks zum Erweitern oder Verkleinern der Box
|
||||
GestureDetector(
|
||||
onTap: () {
|
||||
setState(() {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
import 'package:flutter/cupertino.dart';
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
// Funktion zum Erstellen eines Eingabe-Widgets
|
||||
Widget buildInputWidget(String label, TextEditingController controller, FocusNode focusNode, bool isValid, String suffixText, String tooltipText) {
|
||||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
|
@ -8,6 +9,7 @@ Widget buildInputWidget(String label, TextEditingController controller, FocusNod
|
|||
Row(
|
||||
mainAxisAlignment: MainAxisAlignment.spaceBetween,
|
||||
children: [
|
||||
// Zeile für das Label und den Tooltip
|
||||
Row(
|
||||
children: [
|
||||
Row(
|
||||
|
@ -42,6 +44,7 @@ Widget buildInputWidget(String label, TextEditingController controller, FocusNod
|
|||
],
|
||||
),
|
||||
const SizedBox(height: 5),
|
||||
// Textfeld für die Eingabe
|
||||
CupertinoTextField(
|
||||
controller: controller,
|
||||
focusNode: focusNode,
|
||||
|
|
|
@ -3,6 +3,7 @@ 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;
|
||||
|
@ -22,6 +23,7 @@ class _IntervalWidgetState extends State<IntervalWidget> {
|
|||
return Column(
|
||||
crossAxisAlignment: CrossAxisAlignment.start,
|
||||
children: [
|
||||
// Überschrift für das Dropdown-Menü
|
||||
const Row(
|
||||
children: [
|
||||
Text(
|
||||
|
@ -38,6 +40,7 @@ class _IntervalWidgetState extends State<IntervalWidget> {
|
|||
),
|
||||
]
|
||||
),
|
||||
// Dropdown-Menü
|
||||
CupertinoTextField(
|
||||
placeholder: 'Ausschüttungsintervall auswählen',
|
||||
readOnly: true,
|
||||
|
@ -49,6 +52,7 @@ class _IntervalWidgetState extends State<IntervalWidget> {
|
|||
return Column(
|
||||
mainAxisSize: MainAxisSize.min,
|
||||
children: [
|
||||
// Liste von Auswahlmöglichkeiten
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 8.0),
|
||||
child: ListTile(
|
||||
|
@ -61,6 +65,7 @@ class _IntervalWidgetState extends State<IntervalWidget> {
|
|||
hoverColor: Colors.transparent,
|
||||
trailing: widget.selectedInterval == translateInterval(PayoutInterval.yearly) ? const Icon(CupertinoIcons.checkmark_alt) : null,
|
||||
onTap: () {
|
||||
// Auswahl des jährlichen Intervalls und Schließen des Bottom Sheets
|
||||
widget.onChanged(translateInterval(PayoutInterval.yearly));
|
||||
Navigator.pop(context);
|
||||
},
|
||||
|
@ -78,6 +83,7 @@ class _IntervalWidgetState extends State<IntervalWidget> {
|
|||
hoverColor: Colors.transparent,
|
||||
trailing: widget.selectedInterval == translateInterval(PayoutInterval.monthly) ? const Icon(CupertinoIcons.checkmark_alt) : null,
|
||||
onTap: () {
|
||||
// Auswahl des monatlichen Intervalls und Schließen des Bottom Sheets
|
||||
widget.onChanged(translateInterval(PayoutInterval.monthly));
|
||||
Navigator.pop(context);
|
||||
},
|
||||
|
|
|
@ -4,7 +4,9 @@ import 'package:flutter_application_1/translations.dart';
|
|||
import 'package:flutter_application_1/widgets/expandable_widget.dart';
|
||||
import 'package:flutter_application_1/widgets/chart_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.
|
||||
List<Map<String, dynamic>> milestoneList = [
|
||||
{'value': 1329, 'image': 'iphone-15-pro-model.png', 'text': 'iPhone 15 Pro Max\nPreis: 1329€', 'size': 20},
|
||||
{'value': 3071, 'image': 'flyer-gotour6-model.png', 'text': 'Flyer Gotour6 3.40\nPreis: 3071€', 'size': 70},
|
||||
|
@ -60,12 +62,14 @@ 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 milestoneImage = milestones[index]['image'];
|
||||
String milestoneText = milestones[index]['text'];
|
||||
|
@ -73,7 +77,7 @@ Widget buildMilestoneTimeline(List<Map<String, dynamic>> milestones, double tota
|
|||
bool milestoneReached = totalInterest >= milestoneValue;
|
||||
return Column(
|
||||
children: [
|
||||
if (index < milestones.length && index > 0)
|
||||
if (index < milestones.length && index > 0) // Zeigt eine vertikale Linie an zwischen den Meilensteinen
|
||||
Container(
|
||||
height: 50,
|
||||
width: 2,
|
||||
|
@ -88,7 +92,7 @@ Widget buildMilestoneTimeline(List<Map<String, dynamic>> milestones, double tota
|
|||
width: milestoneSize,
|
||||
fit: BoxFit.cover,
|
||||
),
|
||||
const SizedBox(height: 5), // Abstand zwischen Bild und Text
|
||||
const SizedBox(height: 5),
|
||||
Text(
|
||||
milestoneText,
|
||||
textAlign: TextAlign.center,
|
||||
|
@ -99,6 +103,7 @@ Widget buildMilestoneTimeline(List<Map<String, dynamic>> milestones, double tota
|
|||
],
|
||||
),
|
||||
),
|
||||
// Zeigt ein Häkchen oder einen Kreis je nach Erreichen des Meilensteins an
|
||||
Padding(
|
||||
padding: const EdgeInsets.symmetric(vertical: 4.0),
|
||||
child: Icon(
|
||||
|
|
Loading…
Reference in New Issue