diff --git a/android/app/build.gradle b/android/app/build.gradle
index 4d3532ef..4563361f 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -20,12 +20,12 @@ if (project.hasProperty('google-services.json')) {
def flutterVersionCode = localProperties.getProperty("flutter.versionCode")
if (flutterVersionCode == null) {
- flutterVersionCode = "43"
+ flutterVersionCode = "44"
}
def flutterVersionName = localProperties.getProperty("flutter.versionName")
if (flutterVersionName == null) {
- flutterVersionName = "1.0.42"
+ flutterVersionName = "1.0.43"
}
def keystorePropertiesFile = rootProject.file("key.properties")
diff --git a/android/app/src/main/AndroidManifest.xml b/android/app/src/main/AndroidManifest.xml
index 7c97326e..f1091bc0 100644
--- a/android/app/src/main/AndroidManifest.xml
+++ b/android/app/src/main/AndroidManifest.xml
@@ -30,13 +30,27 @@
+
+
+
+
+
+
+
+
diff --git a/lib/config/my_router.dart b/lib/config/my_router.dart
index 23a8dff9..52e6906b 100644
--- a/lib/config/my_router.dart
+++ b/lib/config/my_router.dart
@@ -667,7 +667,8 @@ final GoRouter router = GoRouter(
redirect: (context, state) async {
if (state.uri.path == '/SessionCheckScreen' ||
state.uri.path == '/login' ||
- state.uri.path == '/register') {
+ state.uri.path == '/register' ||
+ state.uri.path == '/forgot-password/:email') {
return null;
}
diff --git a/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart b/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart
index 8438fb8b..a9e03fbc 100644
--- a/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart
+++ b/lib/presentation/Screens/Bottom Navigation Pages/UAE_Numbers/uae_numbers.dart
@@ -240,7 +240,8 @@ class _UaenumberWidgetState extends ConsumerState {
onChanged: (value) {
filterData(
value); // Call filter function directly on input change
- },
+ }, // Ensures vertical alignment
+ // Centers text horizontally
decoration: InputDecoration(
hintText: AppLocalizations.of(context)!.search,
hintStyle: TextStyle(color: Color(0xFFAA8E83)),
@@ -261,8 +262,9 @@ class _UaenumberWidgetState extends ConsumerState {
// // fit: BoxFit.contain,
// ),
border: InputBorder.none,
- contentPadding:
- EdgeInsets.symmetric(vertical: 9, horizontal: 18.0),
+ // contentPadding:
+ // EdgeInsets.symmetric(vertical: 9, horizontal: 18.0),
+ contentPadding: EdgeInsets.zero,
),
),
),
diff --git a/lib/presentation/Screens/auth_verification/forgot_password.dart b/lib/presentation/Screens/auth_verification/forgot_password.dart
index 9ee944a5..6a01c344 100644
--- a/lib/presentation/Screens/auth_verification/forgot_password.dart
+++ b/lib/presentation/Screens/auth_verification/forgot_password.dart
@@ -107,6 +107,66 @@ class _ForgotPasswordState extends ConsumerState {
return null;
}
+ // Future updatePassword(
+ // String email, String oldPassword, String newPassword) async {
+ // print(email);
+ // try {
+ // setState(() {
+ // isLoading = true;
+ // });
+ // // Authenticate as admin
+ // final adminAuth = await _pb.admins
+ // .authWithPassword('pb@venbainfotech.com', 'pb@venbainfotech.com');
+ // final token = adminAuth.token;
+ //
+ // final headers = {
+ // 'Authorization': 'Bearer $token',
+ // };
+ //
+ // // Update password
+ // await _pb.collection('users').update(
+ // email,
+ // body: {
+ // 'password': newPassword,
+ // 'passwordConfirm': newPassword,
+ // },
+ // headers: headers,
+ // );
+ //
+ // setState(() {
+ // isLoading = false;
+ // _isPasswordUpdated = true;
+ // });
+ //
+ // ScaffoldMessenger.of(context).showSnackBar(
+ // SnackBar(
+ // content:
+ // Text(AppLocalizations.of(context)!.password_update_successfully),
+ // backgroundColor: Colors.green,
+ // ),
+ // );
+ //
+ // print('_isPasswordUpdated $_isPasswordUpdated');
+ //
+ // // Navigator.push(
+ // // context,
+ // // MaterialPageRoute(
+ // // builder: (context) => ProfileScreen(userId: userId)),
+ // // );
+ // } catch (e) {
+ // setState(() {
+ // isLoading = false;
+ // });
+ // ScaffoldMessenger.of(context).showSnackBar(
+ // SnackBar(
+ // content: Text(context.translate(
+ // 'Failed to update password: $e', 'فشل في تحديث كلمة المرور')),
+ // backgroundColor: Colors.red,
+ // ),
+ // );
+ // }
+ // }
+
Future updatePassword(
String email, String oldPassword, String newPassword) async {
try {
@@ -122,9 +182,27 @@ class _ForgotPasswordState extends ConsumerState {
'Authorization': 'Bearer $token',
};
- // Update password
+ // Step 1: Find User by Email
+ final result = await _pb.collection('users').getList(
+ filter: 'email = "$email"',
+ headers: headers,
+ );
+
+ if (result.items.isEmpty) {
+ // throw Exception("User not found");
+ ScaffoldMessenger.of(context).showSnackBar(
+ SnackBar(
+ content: Text('User not found'),
+ backgroundColor: Colors.red,
+ ),
+ );
+ }
+
+ final userId = result.items.first.id;
+
+ // Step 3: Update Password
await _pb.collection('users').update(
- email,
+ userId,
body: {
'password': newPassword,
'passwordConfirm': newPassword,
@@ -146,19 +224,14 @@ class _ForgotPasswordState extends ConsumerState {
);
print('_isPasswordUpdated $_isPasswordUpdated');
-
- // Navigator.push(
- // context,
- // MaterialPageRoute(
- // builder: (context) => ProfileScreen(userId: userId)),
- // );
} catch (e) {
setState(() {
isLoading = false;
});
+
ScaffoldMessenger.of(context).showSnackBar(
SnackBar(
- content: Text(context.translate('Failed to update password: $e','فشل في تحديث كلمة المرور')),
+ content: Text('Failed to update password: $e'),
backgroundColor: Colors.red,
),
);
diff --git a/lib/presentation/Screens/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart
index b297195c..dd771b50 100644
--- a/lib/presentation/Screens/charts/screens/chart_screen.dart
+++ b/lib/presentation/Screens/charts/screens/chart_screen.dart
@@ -2695,50 +2695,54 @@ class _ChartScreen1State extends ConsumerState {
}
}
-Future shareCurrentPage(BuildContext context, bool _isSharing) async {
- if (_isSharing) return; // Prevent multiple taps
+Future shareCurrentPage(BuildContext context, bool isSharing) async {
+ if (isSharing) return; // Prevent multiple taps
- _isSharing = true;
+ isSharing = true;
try {
final String currentRoute = GoRouterState.of(context).uri.toString();
- final String baseAppLink = 'https://fcsc-a161c.web.app';
+ final String baseAppLink = 'https://www.fcsc.com';
final String shareLink = '$baseAppLink$currentRoute';
- final String shareText = 'Check this out!';
- final String svgAssetPath = 'assets/backgrounds/share/fcsc.svg';
+ final String shareText = 'Check this out!\n\n$shareLink';
+ print('Generated Share Link: $shareLink');
+ // Optional: Capture SVG to image
+ final String svgAssetPath = 'assets/backgrounds/share/fcsc.svg';
final screenshotController = ScreenshotController();
final svgWidget = SvgPicture.asset(
svgAssetPath,
width: 200,
height: 200,
);
+
final Uint8List? capturedImage =
await screenshotController.captureFromWidget(
Material(child: svgWidget),
);
if (capturedImage == null) {
- throw Exception('Failed to capture SVG as image');
+ print('SVG capture failed, proceeding without image.');
+ await Share.share(shareText, subject: 'App Link');
+ } else {
+ final directory = await getTemporaryDirectory();
+ final file = File('${directory.path}/share_image.png');
+ await file.writeAsBytes(capturedImage);
+
+ await Share.shareXFiles(
+ [XFile(file.path)],
+ text: shareText,
+ subject: 'Shared Content',
+ );
+
+ await file.delete();
}
-
- final directory = await getTemporaryDirectory();
- final file = File('${directory.path}/share.svg');
- await file.writeAsBytes(capturedImage);
-
- await Share.shareXFiles(
- [XFile(file.path)],
- text: '$shareText\n$shareLink',
- subject: 'Shared Content',
- );
-
- await file.delete();
} catch (e) {
- print("Error sharing file: $e");
+ print("Error sharing content: $e");
ScaffoldMessenger.of(context).showSnackBar(
- SnackBar(content: Text('Error sharing: $e')),
+ SnackBar(content: Text('Error sharing: ${e.toString()}')),
);
} finally {
- _isSharing = false; // Reset flag after sharing completes
+ isSharing = false; // Reset flag
}
}
diff --git a/lib/presentation/Screens/charts/widgets/chart_widget.dart b/lib/presentation/Screens/charts/widgets/chart_widget.dart
index 195daf1a..5204940f 100644
--- a/lib/presentation/Screens/charts/widgets/chart_widget.dart
+++ b/lib/presentation/Screens/charts/widgets/chart_widget.dart
@@ -4,6 +4,7 @@ import 'dart:math';
import 'package:fl_chart/fl_chart.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
+import 'package:uae_stat/domain/use_cases/language.dart';
// import 'package:syncfusion_flutter_charts/charts.dart';
class ChartWidget extends StatelessWidget {
@@ -204,12 +205,11 @@ class ChartWidget extends StatelessWidget {
return chartData['response']
.where((entry) => entry['ObsKey'][groupByKey] == groupByValue)
.map((entry) {
- return ChartData(
- x: entry['ObsKey']['TIME_PERIOD'],
- y: double.tryParse(entry['ObsValue']['Value']) ?? 0.0,
- );
- })
- .toList();
+ return ChartData(
+ x: entry['ObsKey']['TIME_PERIOD'],
+ y: double.tryParse(entry['ObsValue']['Value']) ?? 0.0,
+ );
+ }).toList();
}
List parseColumnChartData(dynamic chartData) {
@@ -380,7 +380,8 @@ class ChartWidget extends StatelessWidget {
// ];
// }
- List generateIndicators(dynamic chartData, double totalValue) {
+ List generateIndicators(
+ dynamic chartData, double totalValue, BuildContext context) {
var groupByKeyValue;
if (chartData['chart_type_json']['chart_type'] == 'bar_chart_horizontal' ||
chartData['chart_type_json']['chart_type'] == 'horizontal_rotate') {
@@ -412,50 +413,83 @@ class ChartWidget extends StatelessWidget {
}
// double percentage = (value / totalValue) * 100;
- String percentage =
- (totalValue > 0)
- ? ((value / totalValue) * 100).toStringAsFixed(1)
- : "0.0";
+ String percentage = (totalValue > 0)
+ ? ((value / totalValue) * 100).toStringAsFixed(1)
+ : "0.0";
// bool isTouched = index == touchedIndex;
+ // return Wrap(
+ // alignment: WrapAlignment.center,
+ // spacing: 12,
+ // runSpacing: 8,
+ // children: [
+ // Row(
+ // mainAxisSize: MainAxisSize.min,
+ // children: [
+ // Container(
+ // width: 10,
+ // height: 10,
+ // decoration: BoxDecoration(
+ // color: uniqueColors[index % uniqueColors.length],
+ // shape: BoxShape.circle,
+ // ),
+ // ),
+ // SizedBox(width: 8),
+ // Flexible(
+ // child: Text(
+ // context.translate(
+ // '$title -- $percentage%',
+ // '$title -- %$percentage',
+ // ),
+ // textAlign: TextAlign.start,
+ // style: TextStyle(fontSize: 12),
+ // softWrap: true,
+ // maxLines: 2, // Allows wrapping within two lines
+ // overflow: TextOverflow.ellipsis, // Prevents overflow
+ // ),
+ // ),
+ // ],
+ // ),
+ // ],
+ // );
+
return Row(
- mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment:
+ CrossAxisAlignment.start, // Aligns dot to text start
children: [
Container(
width: 10,
height: 10,
+ margin: EdgeInsets.only(top: 4), // Adjust to align with text
decoration: BoxDecoration(
color: uniqueColors[index % uniqueColors.length],
shape: BoxShape.circle,
),
),
SizedBox(width: 8),
- TooltipTheme(
- data: TooltipThemeData(
- decoration: BoxDecoration(
- color: Colors.blueGrey[800], // Change background color
- borderRadius: BorderRadius.circular(
- 8,
- ), // Optional: rounded corners
+ Expanded(
+ child: TooltipTheme(
+ data: TooltipThemeData(
+ decoration: BoxDecoration(
+ color: Colors.blueGrey[800], // Change background color
+ borderRadius: BorderRadius.circular(8),
+ ),
+ textStyle: TextStyle(color: Colors.white),
),
- textStyle: TextStyle(color: Colors.white), // Change text color
- ),
- child: Tooltip(
- message: title, // Full text on hover
- child: ConstrainedBox(
- // Constrain width to allow wrapping
- constraints: BoxConstraints(maxWidth: 250),
+ child: Tooltip(
+ message: title, // Full text on hover
child: Text(
- '$title -- $percentage%',
+ context.translate(
+ '$title -- $percentage%',
+ '$title -- %$percentage',
+ ),
style: TextStyle(fontSize: 12),
softWrap: true,
maxLines: 2,
- // overflow: TextOverflow.ellipsis, // Ensures text doesn't overflow
),
),
),
),
- SizedBox(width: 5),
],
);
}).toList();
@@ -618,17 +652,15 @@ class ChartWidget extends StatelessWidget {
),
);
case 'pie_chart':
- double totalValue = chartData['response']
- .map((entry) {
- var value = entry['ObsValue']['Value'];
- // print('Processing value: $value, type: ${value.runtimeType}');
- return (value is num)
- ? value.toDouble()
- : value is String
+ double totalValue = chartData['response'].map((entry) {
+ var value = entry['ObsValue']['Value'];
+ // print('Processing value: $value, type: ${value.runtimeType}');
+ return (value is num)
+ ? value.toDouble()
+ : value is String
? double.tryParse(value) ?? 0.0
: 0.0;
- })
- .fold(0.0, (prev, element) => prev + element);
+ }).fold(0.0, (prev, element) => prev + element);
ValueNotifier touchedIndex = ValueNotifier(null);
@@ -665,10 +697,8 @@ class ChartWidget extends StatelessWidget {
touchCallback: (FlTouchEvent event, pieTouchResponse) {
if (pieTouchResponse?.touchedSection != null &&
event is! FlTapUpEvent) {
- touchedIndex.value =
- pieTouchResponse!
- .touchedSection!
- .touchedSectionIndex;
+ touchedIndex.value = pieTouchResponse!
+ .touchedSection!.touchedSectionIndex;
} else {
touchedIndex.value =
null; // Reset when not touching
@@ -704,7 +734,8 @@ class ChartWidget extends StatelessWidget {
child: Column(
// Change Row to Column
crossAxisAlignment: CrossAxisAlignment.start,
- children: generateIndicators(chartData, totalValue),
+ children:
+ generateIndicators(chartData, totalValue, context),
),
),
),
@@ -870,48 +901,47 @@ class ChartWidget extends StatelessWidget {
child: Wrap(
spacing: 10, // Horizontal spacing between items
runSpacing: 5, // Vertical spacing between rows
- children:
- chunkedGroupByValues.expand((chunk) {
- return chunk.map((group) {
- List groupByValuesList = groupByValues.toList();
- int index = groupByValuesList.indexOf(group);
- Color groupColor = _getColorForGroup(index);
+ children: chunkedGroupByValues.expand((chunk) {
+ return chunk.map((group) {
+ List groupByValuesList = groupByValues.toList();
+ int index = groupByValuesList.indexOf(group);
+ Color groupColor = _getColorForGroup(index);
- return Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Container(
- width: 10,
- height: 10,
- decoration: BoxDecoration(
- color: groupColor,
- shape: BoxShape.circle,
- ),
- ),
- SizedBox(width: 5),
- Tooltip(
- message: group,
- waitDuration: Duration(milliseconds: 500),
- showDuration: Duration(seconds: 2),
- decoration: BoxDecoration(
- color: Colors.black,
- // color: Colors.blueGrey[900],
- borderRadius: BorderRadius.circular(4),
- ),
- textStyle: TextStyle(color: Colors.white),
- child: Text(
- group,
- // group.length > 10
- // ? '${group.substring(0, 10)}...'
- // : group,
- // overflow: TextOverflow.ellipsis,
- style: TextStyle(fontSize: 11),
- ),
- ),
- ],
- );
- }).toList();
- }).toList(),
+ return Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ width: 10,
+ height: 10,
+ decoration: BoxDecoration(
+ color: groupColor,
+ shape: BoxShape.circle,
+ ),
+ ),
+ SizedBox(width: 5),
+ Tooltip(
+ message: group,
+ waitDuration: Duration(milliseconds: 500),
+ showDuration: Duration(seconds: 2),
+ decoration: BoxDecoration(
+ color: Colors.black,
+ // color: Colors.blueGrey[900],
+ borderRadius: BorderRadius.circular(4),
+ ),
+ textStyle: TextStyle(color: Colors.white),
+ child: Text(
+ group,
+ // group.length > 10
+ // ? '${group.substring(0, 10)}...'
+ // : group,
+ // overflow: TextOverflow.ellipsis,
+ style: TextStyle(fontSize: 11),
+ ),
+ ),
+ ],
+ );
+ }).toList();
+ }).toList(),
),
),
],
@@ -938,13 +968,12 @@ class ChartWidget extends StatelessWidget {
print('LnTrnd1');
// Extract all years from the chart data
- List years =
- (chartData['response'] as List)
- .map(
- (entry) =>
- int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0,
- )
- .toList();
+ List years = (chartData['response'] as List)
+ .map(
+ (entry) =>
+ int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0,
+ )
+ .toList();
// Sort in ascending order
years.sort();
@@ -974,10 +1003,9 @@ class ChartWidget extends StatelessWidget {
// Filter chart data to only include entries within the last 5 years
List filteredData =
(chartData['response'] as List).where((entry) {
- int year =
- int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
- return year >= minYear && year <= maxYear;
- }).toList();
+ int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
+ return year >= minYear && year <= maxYear;
+ }).toList();
print('LnTrnd2 $filteredData');
// Set uniqueXValues = filteredData
@@ -985,32 +1013,31 @@ class ChartWidget extends StatelessWidget {
// (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']))
// .toSet();
- Set uniqueXValues =
- filteredData.map((entry) {
- String? timePeriod =
- entry['ObsKey']['TIME_PERIOD']; // Nullable String
- print('TIME_PERIOD- $timePeriod');
+ Set uniqueXValues = filteredData.map((entry) {
+ String? timePeriod =
+ entry['ObsKey']['TIME_PERIOD']; // Nullable String
+ print('TIME_PERIOD- $timePeriod');
- if (timePeriod == null) {
- print('TIME_PERIOD is null');
- return ''; // Or handle the null case appropriately
- }
+ if (timePeriod == null) {
+ print('TIME_PERIOD is null');
+ return ''; // Or handle the null case appropriately
+ }
- // Check format using regex
- if (RegExp(r'^\d{4}$').hasMatch(timePeriod)) {
- print('Year format detected: $timePeriod');
- return timePeriod; // Year only
- } else if (RegExp(r'^\d{4}-\d{2}$').hasMatch(timePeriod)) {
- print('Year-Month format detected: $timePeriod');
- return timePeriod; // Year-Month
- } else if (RegExp(r'^\d{4}-[A-Za-z]{3}$').hasMatch(timePeriod)) {
- print('Year-MonthAbbr format detected: $timePeriod');
- return timePeriod; // Year-MonthAbbr
- } else {
- print('Unknown format: $timePeriod');
- return timePeriod; // Keep it as is
- }
- }).toSet();
+ // Check format using regex
+ if (RegExp(r'^\d{4}$').hasMatch(timePeriod)) {
+ print('Year format detected: $timePeriod');
+ return timePeriod; // Year only
+ } else if (RegExp(r'^\d{4}-\d{2}$').hasMatch(timePeriod)) {
+ print('Year-Month format detected: $timePeriod');
+ return timePeriod; // Year-Month
+ } else if (RegExp(r'^\d{4}-[A-Za-z]{3}$').hasMatch(timePeriod)) {
+ print('Year-MonthAbbr format detected: $timePeriod');
+ return timePeriod; // Year-MonthAbbr
+ } else {
+ print('Unknown format: $timePeriod');
+ return timePeriod; // Keep it as is
+ }
+ }).toSet();
print("Unique X Values: $uniqueXValues");
@@ -1050,11 +1077,10 @@ class ChartWidget extends StatelessWidget {
throw FormatException("Invalid TIME_PERIOD format: $timePeriod");
}
- Set uniqueXValuesProcessed =
- uniqueXValues
- .where((value) => value.isNotEmpty) // Remove any empty strings
- .map(parseTimePeriod)
- .toSet();
+ Set uniqueXValuesProcessed = uniqueXValues
+ .where((value) => value.isNotEmpty) // Remove any empty strings
+ .map(parseTimePeriod)
+ .toSet();
print('Processed X Values: $uniqueXValuesProcessed');
print('LnTrnd2.1');
@@ -1150,21 +1176,20 @@ class ChartWidget extends StatelessWidget {
child: Wrap(
spacing: 12,
runSpacing: 8,
- children:
- groupByValues.map((group) {
- return Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Container(
- width: 12,
- height: 12,
- color: groupColorMap[group],
- ),
- SizedBox(width: 6),
- Text(group, style: TextStyle(fontSize: 14)),
- ],
- );
- }).toList(),
+ children: groupByValues.map((group) {
+ return Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ width: 12,
+ height: 12,
+ color: groupColorMap[group],
+ ),
+ SizedBox(width: 6),
+ Text(group, style: TextStyle(fontSize: 14)),
+ ],
+ );
+ }).toList(),
),
),
],
@@ -1185,13 +1210,12 @@ class ChartWidget extends StatelessWidget {
// }
// Extract all years from the chart data
- List years =
- (chartData['response'] as List)
- .map(
- (entry) =>
- int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0,
- )
- .toList();
+ List years = (chartData['response'] as List)
+ .map(
+ (entry) =>
+ int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0,
+ )
+ .toList();
if (years.isEmpty) {
// Return an empty chart if no data
@@ -1212,17 +1236,15 @@ class ChartWidget extends StatelessWidget {
// Filter chart data to include only the selected years
List filteredData =
(chartData['response'] as List).where((entry) {
- int year =
- int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
- return selectedYears.contains(year);
- }).toList();
+ int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
+ return selectedYears.contains(year);
+ }).toList();
- Set uniqueXValues =
- filteredData
- .map(
- (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']),
- )
- .toSet();
+ Set uniqueXValues = filteredData
+ .map(
+ (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']),
+ )
+ .toSet();
var chartBarColors = chartData['chart_bar_color'] ?? {};
Map barColorsMap = {};
@@ -1296,8 +1318,7 @@ class ChartWidget extends StatelessWidget {
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
padding: const EdgeInsets.only(right: 40, top: 10),
child: SizedBox(
- width:
- (uniqueXValues.length * 50) +
+ width: (uniqueXValues.length * 50) +
50, // Adjust width dynamically
child: LineChart(
LineChartData(
@@ -1318,21 +1339,20 @@ class ChartWidget extends StatelessWidget {
child: Wrap(
spacing: 12,
runSpacing: 8,
- children:
- groupByValues.map((group) {
- return Row(
- mainAxisSize: MainAxisSize.min,
- children: [
- Container(
- width: 12,
- height: 12,
- color: groupColorMap[group],
- ),
- SizedBox(width: 6),
- Text(group, style: TextStyle(fontSize: 14)),
- ],
- );
- }).toList(),
+ children: groupByValues.map((group) {
+ return Row(
+ mainAxisSize: MainAxisSize.min,
+ children: [
+ Container(
+ width: 12,
+ height: 12,
+ color: groupColorMap[group],
+ ),
+ SizedBox(width: 6),
+ Text(group, style: TextStyle(fontSize: 14)),
+ ],
+ );
+ }).toList(),
),
),
// Chart
@@ -1359,13 +1379,12 @@ class ChartWidget extends StatelessWidget {
// }
// Extract all years from the chart data
- List years =
- (chartData['response'] as List)
- .map(
- (entry) =>
- int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0,
- )
- .toList();
+ List years = (chartData['response'] as List)
+ .map(
+ (entry) =>
+ int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0,
+ )
+ .toList();
if (years.isEmpty) {
// Return an empty chart if no data
@@ -1386,17 +1405,15 @@ class ChartWidget extends StatelessWidget {
// Filter chart data to include only the selected years
List filteredData =
(chartData['response'] as List).where((entry) {
- int year =
- int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
- return selectedYears.contains(year);
- }).toList();
+ int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
+ return selectedYears.contains(year);
+ }).toList();
- Set uniqueXValues =
- filteredData
- .map(
- (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']),
- )
- .toSet();
+ Set uniqueXValues = filteredData
+ .map(
+ (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']),
+ )
+ .toSet();
print('uniqueXValuesLineTrend2- $uniqueXValues');
@@ -1456,8 +1473,7 @@ class ChartWidget extends StatelessWidget {
scrollDirection: Axis.horizontal, // Enable horizontal scrolling
padding: const EdgeInsets.only(right: 40, top: 20),
child: SizedBox(
- width:
- (uniqueXValues.length * 50) +
+ width: (uniqueXValues.length * 50) +
50, // Adjust width dynamically
child: LineChart(
LineChartData(
@@ -1516,13 +1532,11 @@ class ChartWidget extends StatelessWidget {
int.tryParse(b['ObsKey']['TIME_PERIOD'].toString()) ?? 0;
// Extract QUARTER and convert "Q1", "Q2", etc. to numeric values
- int quarterA =
- int.tryParse(
+ int quarterA = int.tryParse(
a['ObsKey']['QUARTER'].toString().replaceAll('Q', ''),
) ??
0;
- int quarterB =
- int.tryParse(
+ int quarterB = int.tryParse(
b['ObsKey']['QUARTER'].toString().replaceAll('Q', ''),
) ??
0;
@@ -1536,22 +1550,44 @@ class ChartWidget extends StatelessWidget {
});
}
+ print('chartData response sort: ${chartData['response']}');
+
// if (xValue != null && yValue != null) {
// xAxisData.add(xValue.toString());
// yAxisData.add(double.tryParse(yValue.toString()) ?? 0.0);
// }
- if (xValue != null && yValue != null) {
- // Check if additional_x_group is "Timeperiod" and concatenate
+ // if (xValue != null && yValue != null) {
+ // // Check if additional_x_group is "Timeperiod" and concatenate
+ // String xLabel = xValue.toString();
+ // if (xadditionalgroup == 'TIME_PERIOD' && xTimePeriod != null) {
+ // xLabel = '$xTimePeriod-$xValue'; // Format: Label (TimePeriod)
+ // }
+ //
+ // xAxisData.add(xLabel);
+ // yAxisData.add(double.tryParse(yValue.toString()) ?? 0.0);
+ // // yAxisLabels.add(unitMsr ?? '');
+ // }
+ }
+ for (var entry in chartData['response']) {
+ var xValue = entry['ObsKey'][groupByKey];
+ var xTimePeriod = entry['ObsKey']['TIME_PERIOD'];
+ var yValue = entry['ObsValue']['Value'];
+ var xadditionalgroup =
+ chartData['chart_type_json']['additional_x_group'];
+
+ if (xValue != null) {
String xLabel = xValue.toString();
if (xadditionalgroup == 'TIME_PERIOD' && xTimePeriod != null) {
xLabel = '$xTimePeriod-$xValue'; // Format: Label (TimePeriod)
}
-
xAxisData.add(xLabel);
+ }
+ if (yValue != null) {
yAxisData.add(double.tryParse(yValue.toString()) ?? 0.0);
- // yAxisLabels.add(unitMsr ?? '');
}
}
+ print('xAxisData $xAxisData');
+ print('yAxisData $yAxisData');
return Column(
children: [
Text(
@@ -1581,26 +1617,23 @@ class ChartWidget extends StatelessWidget {
constraints: BoxConstraints(
minWidth:
screenWidth, // Ensure it at least fills available width
- maxWidth:
- chartWidth > screenWidth
- ? chartWidth
- : screenWidth, // Prevent non-normalized constraints
+ maxWidth: chartWidth > screenWidth
+ ? chartWidth
+ : screenWidth, // Prevent non-normalized constraints
),
child: Center(
child: SizedBox(
- width:
- xAxisData.length *
+ width: xAxisData.length *
(40 + 10), // Bar width + manual spacing
child: BarChart(
BarChartData(
alignment: BarChartAlignment.spaceAround,
- maxY:
- yAxisData.isNotEmpty
- ? yAxisData.reduce(
- (a, b) => a > b ? a : b,
- ) *
- 1.2
- : 10,
+ maxY: yAxisData.isNotEmpty
+ ? yAxisData.reduce(
+ (a, b) => a > b ? a : b,
+ ) *
+ 1.2
+ : 10,
// barTouchData: BarTouchData(
// enabled: true,
// touchCallback: (FlTouchEvent event, barTouchResponse) {
@@ -1625,8 +1658,8 @@ class ChartWidget extends StatelessWidget {
enabled: false,
handleBuiltInTouches: false,
touchTooltipData: BarTouchTooltipData(
- getTooltipColor:
- (group) => Colors.transparent,
+ getTooltipColor: (group) =>
+ Colors.transparent,
// fitInsideHorizontally: true,
// fitInsideVertically: true,
// tooltipPadding: const EdgeInsets.all(8),
@@ -1648,10 +1681,10 @@ class ChartWidget extends StatelessWidget {
number_format != null &&
chartConversion.isNotEmpty)
? formatNumberConversion(
- rod.toY,
- chartConversion,
- number_format,
- ) // If condition is true
+ rod.toY,
+ chartConversion,
+ number_format,
+ ) // If condition is true
: formatNumber(rod.toY),
const TextStyle(
color: Colors.black,
@@ -1666,13 +1699,12 @@ class ChartWidget extends StatelessWidget {
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: false,
- interval:
- (yAxisData.isNotEmpty
- ? yAxisData.reduce(
- (a, b) => a > b ? a : b,
- ) /
- 5
- : 1),
+ interval: (yAxisData.isNotEmpty
+ ? yAxisData.reduce(
+ (a, b) => a > b ? a : b,
+ ) /
+ 5
+ : 1),
getTitlesWidget: (value, meta) {
return Padding(
padding: const EdgeInsets.only(
@@ -1691,10 +1723,12 @@ class ChartWidget extends StatelessWidget {
getTitlesWidget: (value, meta) {
if (value.toInt() < xAxisData.length) {
String title = xAxisData[value.toInt()];
- String displayTitle =
- title.length > 10
- ? title.substring(0, 10) + '...'
- : title;
+ String displayTitle = title.length > 10
+ ? title.substring(0, 10) + '...'
+ : title;
+ print('barChartVALUECHECKTITLE $title');
+ print(
+ 'barChartVALUECHECK $displayTitle');
return Padding(
padding: const EdgeInsets.only(
@@ -1711,13 +1745,12 @@ class ChartWidget extends StatelessWidget {
child: TooltipTheme(
data: TooltipThemeData(
decoration: BoxDecoration(
- color:
- Colors
- .blueGrey[800], // Change background color
+ color: Colors.blueGrey[
+ 800], // Change background color
borderRadius:
BorderRadius.circular(
- 8,
- ), // Optional: rounded corners
+ 8,
+ ), // Optional: rounded corners
),
textStyle: TextStyle(
color: Colors.white,
@@ -1726,14 +1759,13 @@ class ChartWidget extends StatelessWidget {
child: TooltipTheme(
data: TooltipThemeData(
decoration: BoxDecoration(
- color:
- Colors
- .black, // Change background color
+ color: Colors
+ .black, // Change background color
// color: Colors.blueGrey[800], // Change background color
borderRadius:
BorderRadius.circular(
- 8,
- ), // Optional: rounded corners
+ 8,
+ ), // Optional: rounded corners
),
textStyle: TextStyle(
color: Colors.white,
@@ -1844,10 +1876,9 @@ class ChartWidget extends StatelessWidget {
});
// If no valid TIME_PERIOD with a month is found, return original response
- List