diff --git a/lib/controller/home_controller.dart b/lib/controller/home_controller.dart index 892fb21..02d2eb5 100644 --- a/lib/controller/home_controller.dart +++ b/lib/controller/home_controller.dart @@ -215,7 +215,7 @@ class HomeController extends GetxController { return 'http://localhost:3000/invoke/IFN_ASKI_Service.flows/getAskiData?'; } else { // Produktion: Direkt an den Server oder über den Produktions-Proxy - return 'http://atwmdv04:5556/invoke/IFN_ASKI_Service.flows/getAskiData?'; + return 'http://localhost:3000/invoke/IFN_ASKI_Service.flows/getAskiData?'; // ODER bei Nginx-Proxy: '/api/IFN_ASKI_Service.flows/getAskiData?' } } diff --git a/lib/widgets/comparison_bar_chart.dart b/lib/widgets/comparison_bar_chart.dart index ecdcefc..db7d263 100644 --- a/lib/widgets/comparison_bar_chart.dart +++ b/lib/widgets/comparison_bar_chart.dart @@ -75,7 +75,12 @@ class ComparisonBarChart extends StatelessWidget { return SingleChildScrollView( child: Padding( - padding: const EdgeInsets.all(16.0), + padding: const EdgeInsets.only( + left: 26.0, + right: 35.0, + top: 16.0, + bottom: 16.0, + ), child: Column( mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.center, @@ -92,6 +97,52 @@ class ComparisonBarChart extends StatelessWidget { height: 500, child: BarChart( BarChartData( + barTouchData: BarTouchData( + enabled: true, + touchTooltipData: BarTouchTooltipData( + // Optional: Hintergrundfarbe und Styling des Tooltips anpassen + getTooltipItem: (group, groupIndex, rod, rodIndex) { + // 1. Datum/Uhrzeit anhand des groupIndex abrufen + final rawDateTime = displayDatetimes[groupIndex]; + + // 2. Formatieren zu "20.07.26 12:00" + String formattedDateTime = rawDateTime; + try { + final parsedDate = DateTime.parse(rawDateTime); + final day = parsedDate.day.toString().padLeft(2, '0'); + final month = parsedDate.month.toString().padLeft( + 2, + '0', + ); + final year = parsedDate.year.toString().substring(2); + final hour = parsedDate.hour.toString().padLeft( + 2, + '0', + ); + final minute = parsedDate.minute.toString().padLeft( + 2, + '0', + ); + formattedDateTime = '$day.$month.$year $hour:$minute'; + } catch (_) {} + + // 3. Typ bestimmen (z.B. PV oder Import je nach Rod-Index) + final label = rodIndex == 0 ? 'PV' : 'Import'; + final unit = 'kW'; + + // 4. Nur beim ersten Ballekn der Gruppe das Datum als Header einfügen + // (sonst würde es bei jedem Einzelbalken doppelt stehen) + return BarTooltipItem( + '$formattedDateTime\n$label: ${rod.toY.round()} $unit', + const TextStyle( + color: Colors.white, + fontWeight: FontWeight.bold, + fontSize: 12, + ), + ); + }, + ), + ), alignment: BarChartAlignment.spaceAround, maxY: maxValue * 1.02, minY: 0, @@ -112,7 +163,7 @@ class ComparisonBarChart extends StatelessWidget { // PV Maximum - oranger Pin if (index == maxPvIndex) { return Transform.translate( - offset: const Offset(-5, 0), + offset: const Offset(0, 0), child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -122,7 +173,9 @@ class ComparisonBarChart extends StatelessWidget { borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( - color: Colors.grey.withValues(alpha: 0.3), + color: Colors.grey.withValues( + alpha: 0.3, + ), blurRadius: 4, ), ], @@ -153,7 +206,7 @@ class ComparisonBarChart extends StatelessWidget { // Import Maximum - roter Pin if (index == maxImportIndex) { return Transform.translate( - offset: const Offset(5, 0), + offset: const Offset(3, 0), child: Column( mainAxisSize: MainAxisSize.min, children: [ @@ -163,7 +216,9 @@ class ComparisonBarChart extends StatelessWidget { borderRadius: BorderRadius.circular(16), boxShadow: [ BoxShadow( - color: Colors.grey.withValues(alpha: 0.3), + color: Colors.grey.withValues( + alpha: 0.3, + ), blurRadius: 4, ), ], @@ -213,24 +268,71 @@ class ComparisonBarChart extends StatelessWidget { bottomTitles: AxisTitles( sideTitles: SideTitles( showTitles: true, - reservedSize: 60, + reservedSize: 40, // Platz für die normale Textzeile getTitlesWidget: (value, meta) { final index = value.toInt(); if (index < 0 || index >= displayDatetimes.length) { return const SizedBox(); } - final datetime = displayDatetimes[index]; - // Extrahiere nur Uhrzeit (HH:mm) - final timePart = datetime.contains('T') - ? datetime.split('T').last.substring(0, 5) - : datetime.substring(0, 5); + + // 1. Indizes für Start, Mitte und Ende bestimmen + final firstIndex = 0; + final lastIndex = displayDatetimes.length - 1; + final middleIndex = displayDatetimes.length ~/ 2; + + // 2. Nur anzeigen, wenn es Start, Mitte oder Ende ist + final isFirst = index == firstIndex; + final isMiddle = + index == middleIndex && + displayDatetimes.length > 2; + final isLast = + index == lastIndex && displayDatetimes.length > 1; + + if (!isFirst && !isMiddle && !isLast) { + return const SizedBox(); // Für alle anderen Balken ausblenden + } + + final datetimeRaw = displayDatetimes[index]; + + // 3. Formatiere den String zu "DD.MM.YY HH:mm" + String formattedDateTime = datetimeRaw; + try { + final parsedDate = DateTime.parse(datetimeRaw); + final day = parsedDate.day.toString().padLeft( + 2, + '0', + ); + final month = parsedDate.month.toString().padLeft( + 2, + '0', + ); + final year = parsedDate.year.toString().substring( + 2, + ); // Die letzten 2 Stellen + final hour = parsedDate.hour.toString().padLeft( + 2, + '0', + ); + final minute = parsedDate.minute.toString().padLeft( + 2, + '0', + ); + + formattedDateTime = + '$day.$month.$year $hour:$minute'; + } catch (_) { + // Fallback, falls String kein echtes ISO-Format ist + formattedDateTime = datetimeRaw; + } + + // 4. Liegend (horizontal) ausgeben return Padding( padding: const EdgeInsets.only(top: 8.0), - child: RotatedBox( - quarterTurns: 1, - child: Text( - timePart, - style: const TextStyle(fontSize: 10), + child: Text( + formattedDateTime, + style: const TextStyle( + fontSize: 10, + fontWeight: FontWeight.bold, ), ), ); @@ -296,15 +398,17 @@ class ComparisonBarChart extends StatelessWidget { BarChartRodData( toY: pvValue, color: Colors.orange, - width: 8, - borderRadius: const BorderRadius.vertical(top: Radius.circular(4)), + width: 5, // <-- ERHEBLICH SCHMALER (z.B. 2 oder 3 statt 6/8) + borderRadius: const BorderRadius.vertical(top: Radius.circular(1)), ), // Roter Bar für Import BarChartRodData( toY: importValue, color: Colors.red, - width: 8, - borderRadius: const BorderRadius.vertical(top: Radius.circular(4)), + width: 5, // <-- ERHEBLICH SCHMALER + borderRadius: const BorderRadius.vertical( + top: Radius.circular(2.5), + ), ), ], );