diff --git a/lib/config/api_config.dart b/lib/config/api_config.dart index c32efc27..997fb132 100644 --- a/lib/config/api_config.dart +++ b/lib/config/api_config.dart @@ -1,5 +1,5 @@ // api_config.dart // const String apiUrl = 'http://127.0.0.1:8090'; // const String apiUrl = 'https://pbdev.venbait.in/'; -const String apiUrl = 'https://pb.venbait.in/'; -// const String apiUrl = 'https://pocket.fcsc.gov.ae/'; +// const String apiUrl = 'https://pb.venbait.in/'; +const String apiUrl = 'https://pocket.fcsc.gov.ae/'; diff --git a/lib/presentation/Screens/charts/screens/chart_screen.dart b/lib/presentation/Screens/charts/screens/chart_screen.dart index 35f0165f..ef72284f 100644 --- a/lib/presentation/Screens/charts/screens/chart_screen.dart +++ b/lib/presentation/Screens/charts/screens/chart_screen.dart @@ -106,6 +106,7 @@ class _ChartScreen1State extends ConsumerState { late UserService _userService; late double tourCard; late bool isDarkTheme; + String? _previousTabId; @override void initState() { @@ -144,11 +145,11 @@ class _ChartScreen1State extends ConsumerState { final prefs = await SharedPreferences.getInstance(); final userID = prefs.getString('userId'); try { - final result = await _pb.collection('bookmark').getList( filter: "user_id = '${userID}' && dataset = '${widget.dataSets}'", headers: { - 'Authorization': 'Bearer ${PocketBaseService.authStore.token}' // Pass the admin token + 'Authorization': + 'Bearer ${PocketBaseService.authStore.token}' // Pass the admin token }, ); @@ -168,7 +169,6 @@ class _ChartScreen1State extends ConsumerState { final prefs = await SharedPreferences.getInstance(); final userID = prefs.getString('userId'); try { - final response = await _pb.collection('bookmark').create(body: { 'user_id': userID, 'dataset': widget.dataSets, @@ -1667,6 +1667,45 @@ class _ChartScreen1State extends ConsumerState { Navigator.pop(context); } + void clear() { + print('CLEAR ---'); + + // List> selectedFilters = + // selectedFiltersStorage.isNotEmpty + // ? List.from(selectedFiltersStorage) // Use stored filters + // : filters.map((filter) { + // return {"filter_key": filter["filter_key"], "filter_data": []}; + // }).toList(); // Or initialize empty filters + + // selectedFilters.forEach((filter) { + // filter["filter_data"].clear(); + // }); + setState(() { + chartsData = List.from(originalTabChartsData); + cardData = List.from(originalTabCardData); + }); + selectedFiltersStorage.clear(); + formattedFilters = []; + + final locale = ref.watch(localeProvider)?.languageCode ?? 'en'; + + print('locale22- $locale'); + final isDark = ref.watch(themeProvider) == ThemeMode.dark || + (ref.watch(themeProvider) == ThemeMode.system && + MediaQuery.of(context).platformBrightness == Brightness.dark); + print('isDark filter'); + print(isDark); + final themeMode = (isDark ? 'dark' : 'light'); + print(themeMode); + + // fetchChartData( + // widget.dataSets, + // locale, + // tabWiseKpi, // Ensure you are passing the correct KPI here + // formattedFilters, // Pass the formatted filter data here + // themeMode); + } + String capitalizeAndSplit(String text) { if (text.isEmpty) return text; return text @@ -2025,52 +2064,60 @@ class _ChartScreen1State extends ConsumerState { print( "Selected Filters before applying: $selectedFilters"); - if (selectedFilters.every( - (filter) => filter['filter_data'].isEmpty)) { - setState(() { - isLoading = true; - }); - selectedFilters.forEach((filter) { - filter["filter_data"].clear(); - }); - setState(() { - chartsData = List.from(originalTabChartsData); - cardData = List.from(originalTabCardData); - }); - selectedFiltersStorage.clear(); - formattedFilters = []; + final hasAnyFilterData = selectedFilters.any( + (filter) => + (filter['filter_data'] as List).isNotEmpty, + ); - final locale = - ref.watch(localeProvider)?.languageCode ?? - 'en'; + if (hasAnyFilterData) { + print("⛔ No filter data, resetting"); + if (selectedFilters.every( + (filter) => filter['filter_data'].isEmpty)) { + setState(() { + isLoading = true; + }); + selectedFilters.forEach((filter) { + filter["filter_data"].clear(); + }); + setState(() { + chartsData = List.from(originalTabChartsData); + cardData = List.from(originalTabCardData); + }); + selectedFiltersStorage.clear(); + formattedFilters = []; - print('locale22- $locale'); - final isDark = - ref.watch(themeProvider) == ThemeMode.dark || - (ref.watch(themeProvider) == - ThemeMode.system && - MediaQuery.of(context) - .platformBrightness == - Brightness.dark); + final locale = + ref.watch(localeProvider)?.languageCode ?? + 'en'; - final themeMode = (isDark ? 'dark' : 'light'); - fetchChartData( - widget.dataSets, - locale, - tabWiseKpi, // Ensure you are passing the correct KPI here - formattedFilters, // Pass the formatted filter data here - themeMode); - Navigator.pop(context); - } else { - setState(() { - // isLoading = true; - chartsData = originalTabChartsData; - cardData = originalTabCardData; - }); + print('locale22- $locale'); + final isDark = ref.watch(themeProvider) == + ThemeMode.dark || + (ref.watch(themeProvider) == + ThemeMode.system && + MediaQuery.of(context) + .platformBrightness == + Brightness.dark); - applyFilters(context, filters, chartsData, - cardData, selectedFilters); - // selectedFiltersStorage = List.from(selectedFilters); + final themeMode = (isDark ? 'dark' : 'light'); + fetchChartData( + widget.dataSets, + locale, + tabWiseKpi, // Ensure you are passing the correct KPI here + formattedFilters, // Pass the formatted filter data here + themeMode); + Navigator.pop(context); + } else { + setState(() { + // isLoading = true; + chartsData = originalTabChartsData; + cardData = originalTabCardData; + }); + + applyFilters(context, filters, chartsData, + cardData, selectedFilters); + // selectedFiltersStorage = List.from(selectedFilters); + } } }, style: ElevatedButton.styleFrom( @@ -2121,6 +2168,13 @@ class _ChartScreen1State extends ConsumerState { void onTabSelected(String tabId) { print('Selected Tab on: $tabId'); + + // 🔹 Call clear ONLY if tab changed + // if (_previousTabId != tabId) { + // clear(); + // selectedFiltersStorage.clear(); + // } + tabWiseKpi = tabId; print('Selected Tab tabWiseKpi: $tabWiseKpi'); @@ -3063,20 +3117,36 @@ class _ChartScreen1State extends ConsumerState { // ConstrainedBox Container( height: () { - final chartHeight = chartsData[index]['chart_height']; - final chartType = chartsData[index]['chart_type_json']?['chart_type']; - final responseLength = (chartsData[index]['response'] as List?)?.length ?? 0; + final chartHeight = + chartsData[index] + ['chart_height']; + final chartType = chartsData[ + index] + ['chart_type_json'] + ?['chart_type']; + final responseLength = + (chartsData[index][ + 'response'] + as List?) + ?.length ?? + 0; - if (chartType == 'horizontal_rotate') { + if (chartType == + 'horizontal_rotate') { // Base 350 + add 30 for each response item - return chartHeight + (responseLength * 20.0); + return chartHeight + + (responseLength * 20.0); } - if (chartHeight == null || chartHeight == 0) { + if (chartHeight == null || + chartHeight == 0) { return 350.0; // default } - return double.tryParse(chartHeight.toString()) ?? 350.0; + return double.tryParse( + chartHeight + .toString()) ?? + 350.0; }(), // height: (chartsData[index][ // 'chart_height'] == @@ -3090,7 +3160,6 @@ class _ChartScreen1State extends ConsumerState { // ['chart_height'] // .toString()), - // child: buildChart(chartsData[index]), child: ChartWidget( chartData: @@ -3316,9 +3385,11 @@ class CardWidget extends StatelessWidget { Icon? valueIcon; if (!hideIcon && (response[0]['font_color'] ?? '').isNotEmpty) { if (response[0]['font_color'] == '#D83731') { - valueIcon = const Icon(Icons.arrow_downward, color: Colors.red, size: 20); + valueIcon = + const Icon(Icons.arrow_downward, color: Colors.red, size: 20); } else if (response[0]['font_color'] == '#11AF22') { - valueIcon = const Icon(Icons.arrow_upward, color: Colors.green, size: 20); + valueIcon = + const Icon(Icons.arrow_upward, color: Colors.green, size: 20); } } diff --git a/lib/presentation/Screens/charts/widgets/chart_widget.dart b/lib/presentation/Screens/charts/widgets/chart_widget.dart index ca37d33f..d0547bd7 100644 --- a/lib/presentation/Screens/charts/widgets/chart_widget.dart +++ b/lib/presentation/Screens/charts/widgets/chart_widget.dart @@ -12,10 +12,10 @@ import 'package:d_chart/d_chart.dart'; class ChartWidget extends StatelessWidget { ChartWidget( {Key? key, - required this.chartData, - required this.bodyColor, - required this.chartHeader, - required this.isDarkTheme}) + required this.chartData, + required this.bodyColor, + required this.chartHeader, + required this.isDarkTheme}) : super(key: key); final dynamic chartData; final Color bodyColor; @@ -197,10 +197,10 @@ class ChartWidget extends StatelessWidget { } String formatNumberConversion( - double value, - String chartConversion, - String numberFormat, - ) { + double value, + String chartConversion, + String numberFormat, + ) { // Convert the input value to base unit (actual value) double baseValue = value; @@ -231,10 +231,10 @@ class ChartWidget extends StatelessWidget { } List parseStackedBarChartData( - dynamic chartData, - String groupByKey, - String groupByValue, - ) { + dynamic chartData, + String groupByKey, + String groupByValue, + ) { return chartData['response'] .where((entry) => entry['ObsKey'][groupByKey] == groupByValue) .map((entry) { @@ -314,8 +314,8 @@ class ChartWidget extends StatelessWidget { } return chartData['response'].asMap().entries.map(( - entry, - ) { + entry, + ) { int index = entry.key; var data = entry.value; @@ -354,12 +354,12 @@ class ChartWidget extends StatelessWidget { // displayTitle = '${title.substring(0, endIndex)}...'; displayTitle = - title.length > 12 ? '${title.substring(0, 12)}...' : title; + title.length > 12 ? '${title.substring(0, 12)}...' : title; } else { print("DPT2"); String part1 = title.substring(0, min(12, title.length)); String part2 = - title.length > 12 ? title.substring(12, min(24, title.length)) : ''; + title.length > 12 ? title.substring(12, min(24, title.length)) : ''; displayTitle = part2.isNotEmpty ? '$part1\n-$part2' : part1; } @@ -469,7 +469,7 @@ class ChartWidget extends StatelessWidget { String title = data['ObsKey'][groupByKeyValue] ?? ''; // String value = data['ObsValue']['Value'].toString(); String shortTitle = - title.length > 10 ? '${title.substring(0, 10)}…' : title; + title.length > 10 ? '${title.substring(0, 10)}…' : title; // Handle different types: int, double, and String double value = 0.0; @@ -528,7 +528,7 @@ class ChartWidget extends StatelessWidget { return Row( crossAxisAlignment: - CrossAxisAlignment.start, // Aligns dot to text start + CrossAxisAlignment.start, // Aligns dot to text start children: [ Container( width: 10, @@ -580,9 +580,9 @@ class ChartWidget extends StatelessWidget { } List generateIndicatorsBar( - Map chartData, - List groupByValues, - ) { + Map chartData, + List groupByValues, + ) { List indicators = []; for (int i = 0; i < groupByValues.length; i++) { @@ -655,80 +655,80 @@ class ChartWidget extends StatelessWidget { print('groupByValues $groupByValues'); switch (chartData['chart_type_json']['chart_type']) { - // case 'stacked_bar': - // String chartTitle = - // capitalizeAndSplit(chartData['chart_heading'] ?? ''); - // // Define a list of colors - // final List uniqueColors = [ - // Color(0xFF648CBA), - // Color(0xFF90B0D5), - // Color(0xFF98BCE5), - // Color(0xFFA7B5C5), - // Color(0xFFBED3EC), - // Color(0xFFD4E3F4), - // ]; - // return SfCartesianChart( - // primaryXAxis: CategoryAxis(), - // title: ChartTitle(text: chartData['chart_heading']), - // legend: Legend( - // isVisible: true, - // position: LegendPosition.bottom, - // overflowMode: LegendItemOverflowMode.scroll, - // ), - // tooltipBehavior: TooltipBehavior( - // enable: true, // Enable tooltips - // format: 'point.x : point.y', // Custom tooltip format - // ), - // series: >[ - // for (int i = 0; i < groupByValues.length; i++) - // StackedBarSeries( - // dataSource: parseStackedBarChartData( - // chartData, groupByKey, groupByValues.elementAt(i)), - // xValueMapper: (ChartData data, _) => data.x ?? '', - // yValueMapper: (ChartData data, _) => data.y, - // name: groupByValues.elementAt(i), - // color: uniqueColors[i % uniqueColors.length], - // enableTooltip: true, - // ), - // ], - // ); - // case 'stacked_column': - // String chartTitle = - // capitalizeAndSplit(chartData['chart_heading'] ?? ''); - // // Define a list of colors - // final List uniqueColors = [ - // Color(0xFF648CBA), - // Color(0xFF90B0D5), - // Color(0xFF98BCE5), - // Color(0xFFA7B5C5), - // Color(0xFFBED3EC), - // Color(0xFFD4E3F4), - // ]; - // return SfCartesianChart( - // primaryXAxis: CategoryAxis(), - // title: ChartTitle(text: chartData['chart_heading']), - // legend: Legend( - // isVisible: true, - // position: LegendPosition.bottom, - // overflowMode: LegendItemOverflowMode.scroll, - // ), - // tooltipBehavior: TooltipBehavior( - // enable: true, // Enable tooltips - // format: 'point.x : point.y', // Custom tooltip format - // ), - // series: >[ - // for (int i = 0; i < groupByValues.length; i++) - // StackedColumnSeries( - // dataSource: parseStackedBarChartData( - // chartData, groupByKey, groupByValues.elementAt(i)), - // xValueMapper: (ChartData data, _) => data.x ?? '', - // yValueMapper: (ChartData data, _) => data.y, - // name: groupByValues.elementAt(i), - // color: uniqueColors[i % uniqueColors.length], - // enableTooltip: true, - // ), - // ], - // ); + // case 'stacked_bar': + // String chartTitle = + // capitalizeAndSplit(chartData['chart_heading'] ?? ''); + // // Define a list of colors + // final List uniqueColors = [ + // Color(0xFF648CBA), + // Color(0xFF90B0D5), + // Color(0xFF98BCE5), + // Color(0xFFA7B5C5), + // Color(0xFFBED3EC), + // Color(0xFFD4E3F4), + // ]; + // return SfCartesianChart( + // primaryXAxis: CategoryAxis(), + // title: ChartTitle(text: chartData['chart_heading']), + // legend: Legend( + // isVisible: true, + // position: LegendPosition.bottom, + // overflowMode: LegendItemOverflowMode.scroll, + // ), + // tooltipBehavior: TooltipBehavior( + // enable: true, // Enable tooltips + // format: 'point.x : point.y', // Custom tooltip format + // ), + // series: >[ + // for (int i = 0; i < groupByValues.length; i++) + // StackedBarSeries( + // dataSource: parseStackedBarChartData( + // chartData, groupByKey, groupByValues.elementAt(i)), + // xValueMapper: (ChartData data, _) => data.x ?? '', + // yValueMapper: (ChartData data, _) => data.y, + // name: groupByValues.elementAt(i), + // color: uniqueColors[i % uniqueColors.length], + // enableTooltip: true, + // ), + // ], + // ); + // case 'stacked_column': + // String chartTitle = + // capitalizeAndSplit(chartData['chart_heading'] ?? ''); + // // Define a list of colors + // final List uniqueColors = [ + // Color(0xFF648CBA), + // Color(0xFF90B0D5), + // Color(0xFF98BCE5), + // Color(0xFFA7B5C5), + // Color(0xFFBED3EC), + // Color(0xFFD4E3F4), + // ]; + // return SfCartesianChart( + // primaryXAxis: CategoryAxis(), + // title: ChartTitle(text: chartData['chart_heading']), + // legend: Legend( + // isVisible: true, + // position: LegendPosition.bottom, + // overflowMode: LegendItemOverflowMode.scroll, + // ), + // tooltipBehavior: TooltipBehavior( + // enable: true, // Enable tooltips + // format: 'point.x : point.y', // Custom tooltip format + // ), + // series: >[ + // for (int i = 0; i < groupByValues.length; i++) + // StackedColumnSeries( + // dataSource: parseStackedBarChartData( + // chartData, groupByKey, groupByValues.elementAt(i)), + // xValueMapper: (ChartData data, _) => data.x ?? '', + // yValueMapper: (ChartData data, _) => data.y, + // name: groupByValues.elementAt(i), + // color: uniqueColors[i % uniqueColors.length], + // enableTooltip: true, + // ), + // ], + // ); case 'column_chart': // Case 3 for fl_chart column chart return BarChart( BarChartData( @@ -745,8 +745,8 @@ class ChartWidget extends StatelessWidget { return (value is num) ? value.toDouble() : value is String - ? double.tryParse(value) ?? 0.0 - : 0.0; + ? double.tryParse(value) ?? 0.0 + : 0.0; }).fold(0.0, (prev, element) => prev + element); ValueNotifier touchedIndex = ValueNotifier(null); @@ -798,7 +798,7 @@ class ChartWidget extends StatelessWidget { .touchedSection!.touchedSectionIndex; } else { touchedIndex.value = - null; // Reset when not touching + null; // Reset when not touching } }, ), @@ -832,7 +832,7 @@ class ChartWidget extends StatelessWidget { // Change Row to Column crossAxisAlignment: CrossAxisAlignment.start, children: - generateIndicators(chartData, totalValue, context), + generateIndicators(chartData, totalValue, context), ), ), ), @@ -842,7 +842,7 @@ class ChartWidget extends StatelessWidget { ], ); case 'fl_stacked_bar': - // Divide groupByValuesList into chunks of 5 items per row + // Divide groupByValuesList into chunks of 5 items per row List groupByValuesList = groupByValues.toList(); int chunkSize = 5; List> chunkedGroupByValues = []; @@ -903,11 +903,11 @@ class ChartWidget extends StatelessWidget { tooltipMargin: 16, getTooltipColor: (colorMap) => Colors.black, getTooltipItem: ( - groupData, - groupIndex, - rodData, - rodIndex, - ) { + groupData, + groupIndex, + rodData, + rodIndex, + ) { // Get the list of group names dynamically List groupNames = []; @@ -1106,8 +1106,8 @@ class ChartWidget extends StatelessWidget { List years = (chartData['response'] as List) .map( (entry) => - int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0, - ) + int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0, + ) .toList(); // Sort in ascending order years.sort(); @@ -1137,7 +1137,7 @@ class ChartWidget extends StatelessWidget { // Filter chart data to only include entries within the last 5 years List filteredData = - (chartData['response'] as List).where((entry) { + (chartData['response'] as List).where((entry) { int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0; return year >= minYear && year <= maxYear; }).toList(); @@ -1150,7 +1150,7 @@ class ChartWidget extends StatelessWidget { Set uniqueXValues = filteredData.map((entry) { String? timePeriod = - entry['ObsKey']['TIME_PERIOD']; // Nullable String + entry['ObsKey']['TIME_PERIOD']; // Nullable String print('TIME_PERIOD- $timePeriod'); if (timePeriod == null) { @@ -1236,9 +1236,9 @@ class ChartWidget extends StatelessWidget { // Now map to Color Map parsedChartBarColors = chartBarColrs.map(( - key, - value, - ) { + key, + value, + ) { return MapEntry(key, _hexToColor(value)); }); @@ -1247,10 +1247,10 @@ class ChartWidget extends StatelessWidget { for (String group in groupByValues) { if (hasBarColors && chartData['dataset'] == 'population') { groupColorMap[group] = - parsedChartBarColors[group]!; // Directly assign as Color + parsedChartBarColors[group]!; // Directly assign as Color } else { groupColorMap[group] = - uniqueColors[colorIndex % uniqueColors.length]; + uniqueColors[colorIndex % uniqueColors.length]; } colorIndex++; } @@ -1365,8 +1365,8 @@ class ChartWidget extends StatelessWidget { List years = (chartData['response'] as List) .map( (entry) => - int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0, - ) + int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0, + ) .toList(); if (years.isEmpty) { @@ -1387,7 +1387,7 @@ class ChartWidget extends StatelessWidget { // Filter chart data to include only the selected years List filteredData = - (chartData['response'] as List).where((entry) { + (chartData['response'] as List).where((entry) { int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0; return selectedYears.contains(year); }).toList(); @@ -1395,7 +1395,7 @@ class ChartWidget extends StatelessWidget { Set uniqueXValues = filteredData .map( (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']), - ) + ) .toSet(); var chartBarColors = chartData['chart_bar_color'] ?? {}; @@ -1424,10 +1424,10 @@ class ChartWidget extends StatelessWidget { for (String group in groupByValues) { if (parsedChartBarColors.containsKey(group)) { groupColorMap[group] = - parsedChartBarColors[group]!; // Directly assign as Color + parsedChartBarColors[group]!; // Directly assign as Color } else { groupColorMap[group] = - uniqueColors[colorIndex % uniqueColors.length]; + uniqueColors[colorIndex % uniqueColors.length]; } colorIndex++; } @@ -1518,9 +1518,9 @@ class ChartWidget extends StatelessWidget { final chartHeight = constraints.maxHeight; final allSpots = lineBars.expand((line) => line.spots); final minY = - allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); + allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); final maxY = - allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); + allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); final xValues = allSpots.map((e) => e.x).toList(); final minX = xValues.reduce((a, b) => a < b ? a : b).toInt(); @@ -1533,7 +1533,7 @@ class ChartWidget extends StatelessWidget { return Column( crossAxisAlignment: - CrossAxisAlignment.center, // ensures center alignment + CrossAxisAlignment.center, // ensures center alignment children: [ Padding( padding: const EdgeInsets.only(top: 0), @@ -1572,7 +1572,8 @@ class ChartWidget extends StatelessWidget { color: isDarkTheme ? Colors.white : Colors.black, - fontSize: 10, + fontSize: 9.5, + letterSpacing: -0.5, ); // Show only for full years @@ -1588,9 +1589,11 @@ class ChartWidget extends StatelessWidget { color: isDarkTheme ? Colors.white : Colors.black, - margin: - EdgeInsets.only(bottom: 2), + margin: EdgeInsets.only( + bottom: 2, + ), ), + Text(value.toInt().toString(), style: style), ], @@ -1598,7 +1601,7 @@ class ChartWidget extends StatelessWidget { } return const SizedBox.shrink(); }, - reservedSize: 30, + reservedSize: 42, interval: 1, ), ), @@ -1659,15 +1662,15 @@ class ChartWidget extends StatelessWidget { final xPos = ((spot.x - minX) / (maxX - minX)) * chartWidth; final yPos = (1 - - (spot.y - chartMinY) / - (chartMaxY - chartMinY)) * + (spot.y - chartMinY) / + (chartMaxY - chartMinY)) * chartHeight; // Prevent label from going outside on the left double adjustedLeft = math.max(0, xPos - 30); return Stack(children: [ Positioned( left: - adjustedLeft, // fine-tune horizontal position + adjustedLeft, // fine-tune horizontal position top: yPos - 60, // fine-tune vertical position child: Text( formatNumber(spot.y), @@ -1707,7 +1710,7 @@ class ChartWidget extends StatelessWidget { style: TextStyle( fontSize: 14, fontFamily: - context.translate('Roboto', 'NotoKufi'), + context.translate('Roboto', 'NotoKufi'), ), ), ], @@ -1733,8 +1736,8 @@ class ChartWidget extends StatelessWidget { List years = (chartData['response'] as List) .map( (entry) => - int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0, - ) + int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0, + ) .toList(); if (years.isEmpty) { @@ -1755,7 +1758,7 @@ class ChartWidget extends StatelessWidget { // Filter chart data to include only the selected years List filteredData = - (chartData['response'] as List).where((entry) { + (chartData['response'] as List).where((entry) { int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0; return selectedYears.contains(year); }).toList(); @@ -1763,7 +1766,7 @@ class ChartWidget extends StatelessWidget { Set uniqueXValues = filteredData .map( (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']), - ) + ) .toSet(); var chartBarColors = chartData['chart_bar_color'] ?? {}; @@ -1792,10 +1795,10 @@ class ChartWidget extends StatelessWidget { for (String group in groupByValues) { if (parsedChartBarColors.containsKey(group)) { groupColorMap[group] = - parsedChartBarColors[group]!; // Directly assign as Color + parsedChartBarColors[group]!; // Directly assign as Color } else { groupColorMap[group] = - uniqueColors[colorIndex % uniqueColors.length]; + uniqueColors[colorIndex % uniqueColors.length]; } colorIndex++; } @@ -1909,9 +1912,9 @@ class ChartWidget extends StatelessWidget { final chartHeight = constraints.maxHeight; final allSpots = lineBars.expand((line) => line.spots); final minY = - allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); + allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); final maxY = - allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); + allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); final xValues = allSpots.map((e) => e.x).toList(); final minX = xValues.reduce((a, b) => a < b ? a : b).toInt(); @@ -1924,7 +1927,7 @@ class ChartWidget extends StatelessWidget { return Column( crossAxisAlignment: - CrossAxisAlignment.center, // ensures center alignment + CrossAxisAlignment.center, // ensures center alignment children: [ Padding( padding: const EdgeInsets.only(top: 0), @@ -1963,7 +1966,8 @@ class ChartWidget extends StatelessWidget { color: isDarkTheme ? Colors.white : Colors.black, - fontSize: 10, + fontSize: 9.5, + letterSpacing: -0.5, ); // Show only for full years @@ -1980,7 +1984,7 @@ class ChartWidget extends StatelessWidget { ? Colors.white : Colors.black, margin: - EdgeInsets.only(bottom: 2), + EdgeInsets.only(bottom: 2), ), Text(value.toInt().toString(), style: style), @@ -1989,7 +1993,7 @@ class ChartWidget extends StatelessWidget { } return const SizedBox.shrink(); }, - reservedSize: 30, + reservedSize: 42, interval: 1, ), ), @@ -2036,7 +2040,7 @@ class ChartWidget extends StatelessWidget { // Check the group name (plantType) from your groupedData order final plantType = - groupedData.keys.toList()[barIndex]; + groupedData.keys.toList()[barIndex]; print('plantType $plantType'); if (plantType != "Male" && @@ -2064,15 +2068,15 @@ class ChartWidget extends StatelessWidget { final xPos = ((spot.x - minX) / (maxX - minX)) * chartWidth; final yPos = (1 - - (spot.y - chartMinY) / - (chartMaxY - chartMinY)) * + (spot.y - chartMinY) / + (chartMaxY - chartMinY)) * chartHeight; // Prevent label from going outside on the left double adjustedLeft = math.max(0, xPos - 30); return Stack(children: [ Positioned( left: - adjustedLeft, // fine-tune horizontal position + adjustedLeft, // fine-tune horizontal position top: yPos - 70, // fine-tune vertical position child: Text( formatNumber(spot.y), @@ -2121,7 +2125,7 @@ class ChartWidget extends StatelessWidget { ), ); case 'bar_chart': - // Extract groupBy values and their corresponding y-axis values + // Extract groupBy values and their corresponding y-axis values List xAxisData = []; List yAxisData = []; List yAxisLabels = []; @@ -2138,7 +2142,7 @@ class ChartWidget extends StatelessWidget { var unitMsr = entry['ObsKey']['UNIT_MEASURE']; var yValue = entry['ObsValue']['Value']; var xadditionalgroup = - chartData['chart_type_json']['additional_x_group']; + chartData['chart_type_json']['additional_x_group']; print('chartData response: ${chartData['response']}'); @@ -2161,12 +2165,12 @@ class ChartWidget extends StatelessWidget { // Extract QUARTER and convert "Q1", "Q2", etc. to numeric values int quarterA = int.tryParse( - a['ObsKey']['QUARTER'].toString().replaceAll('Q', ''), - ) ?? + a['ObsKey']['QUARTER'].toString().replaceAll('Q', ''), + ) ?? 0; int quarterB = int.tryParse( - b['ObsKey']['QUARTER'].toString().replaceAll('Q', ''), - ) ?? + b['ObsKey']['QUARTER'].toString().replaceAll('Q', ''), + ) ?? 0; // First, sort by TIME_PERIOD. If equal, sort by QUARTER @@ -2201,7 +2205,7 @@ class ChartWidget extends StatelessWidget { var xTimePeriod = entry['ObsKey']['TIME_PERIOD']; var yValue = entry['ObsValue']['Value']; var xadditionalgroup = - chartData['chart_type_json']['additional_x_group']; + chartData['chart_type_json']['additional_x_group']; if (xValue != null) { String xLabel = xValue.toString(); @@ -2263,7 +2267,7 @@ class ChartWidget extends StatelessWidget { child: ConstrainedBox( constraints: BoxConstraints( minWidth: - screenWidth, // Ensure it at least fills available width + screenWidth, // Ensure it at least fills available width maxWidth: chartWidth > screenWidth ? chartWidth : screenWidth, // Prevent non-normalized constraints @@ -2277,9 +2281,9 @@ class ChartWidget extends StatelessWidget { alignment: BarChartAlignment.spaceAround, maxY: yAxisData.isNotEmpty ? yAxisData.reduce( - (a, b) => a > b ? a : b, - ) * - 1.2 + (a, b) => a > b ? a : b, + ) * + 1.2 : 10, // barTouchData: BarTouchData( // enabled: true, @@ -2306,36 +2310,36 @@ class ChartWidget extends StatelessWidget { handleBuiltInTouches: false, touchTooltipData: BarTouchTooltipData( getTooltipColor: (group) => - Colors.transparent, + Colors.transparent, // fitInsideHorizontally: true, // fitInsideVertically: true, // tooltipPadding: const EdgeInsets.all(8), tooltipMargin: 1, getTooltipItem: ( - group, - groupIndex, - rod, - rodIndex, - ) { + group, + groupIndex, + rod, + rodIndex, + ) { // String unitMsrLabel = yAxisLabels.isNotEmpty && groupIndex < yAxisLabels.length // ? yAxisLabels[groupIndex] // : ''; // if (rod.toY == 0) return null; final originalValue = - rod.toY == 0.1 ? 0.0 : rod.toY; + rod.toY == 0.1 ? 0.0 : rod.toY; String displayValue; if (originalValue == 0.0) { displayValue = '0'; // 🔥 clean and simple } else { displayValue = (chartConversion != null && - chartConversion.isNotEmpty && - number_format != null && - chartConversion.isNotEmpty) + chartConversion.isNotEmpty && + number_format != null && + chartConversion.isNotEmpty) ? formatNumberConversion( - originalValue, - chartConversion, - number_format, - ) + originalValue, + chartConversion, + number_format, + ) : formatNumber(originalValue); } @@ -2362,9 +2366,9 @@ class ChartWidget extends StatelessWidget { showTitles: false, interval: (yAxisData.isNotEmpty ? yAxisData.reduce( - (a, b) => a > b ? a : b, - ) / - 5 + (a, b) => a > b ? a : b, + ) / + 5 : 1), getTitlesWidget: (value, meta) { return Padding( @@ -2375,9 +2379,9 @@ class ChartWidget extends StatelessWidget { '${value.toInt()}', style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), ); }, @@ -2409,7 +2413,7 @@ class ChartWidget extends StatelessWidget { ), child: SizedBox( width: - 100, // Limit width to force wrapping + 100, // Limit width to force wrapping child: Transform.rotate( // angle: -0.5, angle: 0, @@ -2423,13 +2427,13 @@ class ChartWidget extends StatelessWidget { .black, // Change background color // color: Colors.blueGrey[800], // Change background color borderRadius: - BorderRadius.circular( + BorderRadius.circular( 8, ), // Optional: rounded corners ), textStyle: TextStyle( fontFamily: - context.translate( + context.translate( 'Roboto', 'NotoKufi', ), @@ -2446,7 +2450,7 @@ class ChartWidget extends StatelessWidget { textAlign: TextAlign.center, style: TextStyle( fontFamily: - context.translate( + context.translate( 'Roboto', 'NotoKufi', ), @@ -2546,7 +2550,7 @@ class ChartWidget extends StatelessWidget { ], ); case 'bar_chart_horizontal': - // Extract groupBy values and their corresponding y-axis values + // Extract groupBy values and their corresponding y-axis values List xAxisData = []; List yAxisData = []; List> sortedData = []; @@ -2645,13 +2649,13 @@ class ChartWidget extends StatelessWidget { return BarTooltipItem( // formatNumber(rod.toY), (chartConversion != null && - chartConversion.isNotEmpty && - number_format != null) + chartConversion.isNotEmpty && + number_format != null) ? formatNumberConversion( - rod.toY, - chartConversion, - number_format, - ) + rod.toY, + chartConversion, + number_format, + ) : formatNumber(rod.toY), TextStyle( fontFamily: context.translate( @@ -2680,9 +2684,9 @@ class ChartWidget extends StatelessWidget { '${value.toInt()}', style: TextStyle( fontFamily: context.translate( - 'Roboto', - 'NotoKufi', - )), + 'Roboto', + 'NotoKufi', + )), ), ); }, @@ -2744,7 +2748,7 @@ class ChartWidget extends StatelessWidget { // groupsSpace: 5, barGroups: List.generate( xAxisData.length, - (index) => BarChartGroupData( + (index) => BarChartGroupData( x: index, barsSpace: 20, barRods: [ @@ -2790,9 +2794,9 @@ class ChartWidget extends StatelessWidget { // Now map to Color Map parsedChartBarColors = chartBarColrs.map(( - key, - value, - ) { + key, + value, + ) { return MapEntry(key, _hexToColor(value)); }); print('parsedChartBarColors1100 $parsedChartBarColors'); @@ -2886,7 +2890,7 @@ class ChartWidget extends StatelessWidget { Expanded( child: SingleChildScrollView( scrollDirection: - Axis.horizontal, // Enable horizontal scrolling + Axis.horizontal, // Enable horizontal scrolling child: SizedBox( width: _calculateChartWidth( chartData, @@ -2907,14 +2911,11 @@ class ChartWidget extends StatelessWidget { // ), barGroups: hasBarColors ? _buildHorizontalRotateBarGroupsBarColors( - chartData, - groupByValues, - parsedChartBarColors - ) + chartData, groupByValues, parsedChartBarColors) : _buildHorizontalRotateBarGroups( - chartData, - groupByValues, - ), + chartData, + groupByValues, + ), titlesData: FlTitlesData( leftTitles: AxisTitles( @@ -2924,7 +2925,7 @@ class ChartWidget extends StatelessWidget { sideTitles: SideTitles( showTitles: true, reservedSize: - 130, // Added space for rotated titles + 130, // Added space for rotated titles getTitlesWidget: (value, meta) { if (value < groupByValues.length) { String title = groupByValues.elementAt( @@ -2942,7 +2943,7 @@ class ChartWidget extends StatelessWidget { ), child: SizedBox( width: - 80, // Limit width to force wrapping + 80, // Limit width to force wrapping child: Transform.rotate( angle: -1.5, child: TooltipTheme( @@ -2952,7 +2953,7 @@ class ChartWidget extends StatelessWidget { .black, // Change background color // color: Colors.blueGrey[800], // Change background color borderRadius: - BorderRadius.circular( + BorderRadius.circular( 8, ), // Optional: rounded corners ), @@ -3012,10 +3013,10 @@ class ChartWidget extends StatelessWidget { touchTooltipData: BarTouchTooltipData( getTooltipColor: (group) => Colors.black, tooltipHorizontalAlignment: - FLHorizontalAlignment.center, + FLHorizontalAlignment.center, tooltipRoundedRadius: 8, fitInsideHorizontally: - true, // Ensure it fits within the screen + true, // Ensure it fits within the screen fitInsideVertically: true, tooltipPadding: EdgeInsets.all(8), tooltipMargin: 16, @@ -3075,7 +3076,7 @@ class ChartWidget extends StatelessWidget { children: [ TextSpan( text: - '- ${(chartConversion != null && chartConversion.isNotEmpty && number_format != null) ? formatNumberConversion(rod.toY, chartConversion, number_format) : formatNumber(rod.toY)}', + '- ${(chartConversion != null && chartConversion.isNotEmpty && number_format != null) ? formatNumberConversion(rod.toY, chartConversion, number_format) : formatNumber(rod.toY)}', style: TextStyle( fontFamily: context.translate( 'Roboto', @@ -3120,7 +3121,7 @@ class ChartWidget extends StatelessWidget { case 'horizontal_rotate': String cropKey = chartData['chart_type_json'] - ['y_sub_group']; // Dynamically get crop key + ['y_sub_group']; // Dynamically get crop key // Group crops by CROP_TYPE Map> groupedCrops = {}; @@ -3355,16 +3356,16 @@ class ChartWidget extends StatelessWidget { getTooltipColor: (group) => Colors .transparent, // Light background for visibility tooltipHorizontalAlignment: - FLHorizontalAlignment.center, + FLHorizontalAlignment.center, tooltipRoundedRadius: - 6, // Softer roundness for tooltips + 6, // Softer roundness for tooltips fitInsideHorizontally: true, fitInsideVertically: true, // tooltipPadding: const EdgeInsets.all(5), tooltipPadding: const EdgeInsets.only( top: 8, bottom: 5, left: 5, right: 5), tooltipMargin: - 20, // Reduce margin for better alignment + 20, // Reduce margin for better alignment getTooltipItem: (group, groupIndex, rod, rodIndex) { // if (rod.toY == 0) return null; // Hide for zero values @@ -3421,7 +3422,7 @@ class ChartWidget extends StatelessWidget { 'NotoKufi', ), color: - isDarkTheme ? Colors.white : Colors.black, + isDarkTheme ? Colors.white : Colors.black, fontSize: 12, ), ); @@ -3456,13 +3457,13 @@ class ChartWidget extends StatelessWidget { sideTitles: SideTitles( showTitles: true, reservedSize: (chartData['chart_label_width'] == - null || - chartData['chart_label_width'] == 0) + null || + chartData['chart_label_width'] == 0) ? 150 : (double.tryParse( - chartData['chart_label_width'] - .toString()) ?? - 150), // Added space for rotated titles + chartData['chart_label_width'] + .toString()) ?? + 150), // Added space for rotated titles getTitlesWidget: (value, meta) { if (value < groupByValues.length) { String title = groupByValues.elementAt( @@ -3470,18 +3471,18 @@ class ChartWidget extends StatelessWidget { ); return Transform.rotate( angle: - -1.58, // Rotation in radians (~ -30 degrees) + -1.58, // Rotation in radians (~ -30 degrees) child: Center( child: SizedBox( width: 120, child: Text( title, textAlign: (chartData[ - 'chart_label_width'] == - null || - chartData[ - 'chart_label_width'] == - 0) + 'chart_label_width'] == + null || + chartData[ + 'chart_label_width'] == + 0) ? TextAlign.right : TextAlign.center, style: TextStyle( @@ -3538,14 +3539,14 @@ class ChartWidget extends StatelessWidget { // chartData, groupByValues), barGroups: hasBarColors ? _buildHorizontalRotateBarGroupsBarColors( - chartData, - groupByValues, - parsedChartBarColors, - ) + chartData, + groupByValues, + parsedChartBarColors, + ) : _buildHorizontalRotateBarGroups( - chartData, - groupByValues, - ), + chartData, + groupByValues, + ), alignment: BarChartAlignment.spaceAround, ), @@ -3583,9 +3584,9 @@ class ChartWidget extends StatelessWidget { // Now map to Color Map parsedChartBarColors = chartBarColrs.map(( - key, - value, - ) { + key, + value, + ) { return MapEntry(key, _hexToColor(value)); }); @@ -3598,7 +3599,7 @@ class ChartWidget extends StatelessWidget { groupColorMap[group] = parsedChartBarColors[group]!; } else { groupColorMap[group] = - uniqueColors[colorIndex % uniqueColors.length]; + uniqueColors[colorIndex % uniqueColors.length]; colorIndex++; } } @@ -3609,7 +3610,7 @@ class ChartWidget extends StatelessWidget { List years = (chartData['response'] as List) .map( (entry) => int.tryParse(entry['ObsKey'][groupByKey] ?? '0') ?? 0, - ) + ) .toList(); years.sort(); print(years); @@ -3633,7 +3634,7 @@ class ChartWidget extends StatelessWidget { // Filter chart data to only include entries within the last 5 years List filteredData = - (chartData['response'] as List).where((entry) { + (chartData['response'] as List).where((entry) { int year = int.tryParse(entry['ObsKey'][groupByKey] ?? '0') ?? 0; return year >= minYear && year <= maxYear; }).toList(); @@ -3716,7 +3717,8 @@ class ChartWidget extends StatelessWidget { }); return Scaffold( - backgroundColor: isDarkTheme ? Colors.transparent : Colors.transparent, + backgroundColor: + isDarkTheme ? Colors.transparent : Colors.transparent, body: Padding( padding: const EdgeInsets.all(5), child: LayoutBuilder( @@ -3725,9 +3727,9 @@ class ChartWidget extends StatelessWidget { final chartHeight = constraints.maxHeight; final allSpots = lineBars.expand((line) => line.spots); final minY = - allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); + allSpots.map((e) => e.y).reduce((a, b) => a < b ? a : b); final maxY = - allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); + allSpots.map((e) => e.y).reduce((a, b) => a > b ? a : b); final xValues = allSpots.map((e) => e.x).toList(); final minX = xValues.reduce((a, b) => a < b ? a : b).toInt(); @@ -3740,7 +3742,7 @@ class ChartWidget extends StatelessWidget { return Column( crossAxisAlignment: - CrossAxisAlignment.center, // ensures center alignment + CrossAxisAlignment.center, // ensures center alignment children: [ Padding( padding: const EdgeInsets.only(top: 0), @@ -3784,23 +3786,22 @@ class ChartWidget extends StatelessWidget { // Show only for full years // if (value.toInt() >= 2013 && // value.toInt() <= 2023) { - return Column( - mainAxisSize: MainAxisSize.min, - children: [ - // Top tick mark (simulated using a container) - Container( - width: 1, - height: 8, - color: isDarkTheme - ? Colors.white - : Colors.black, - margin: - EdgeInsets.only(bottom: 2), - ), - Text(value.toInt().toString(), - style: style), - ], - ); + return Column( + mainAxisSize: MainAxisSize.min, + children: [ + // Top tick mark (simulated using a container) + Container( + width: 1, + height: 8, + color: isDarkTheme + ? Colors.white + : Colors.black, + margin: EdgeInsets.only(bottom: 2), + ), + Text(value.toInt().toString(), + style: style), + ], + ); // } return const SizedBox.shrink(); }, @@ -3912,15 +3913,15 @@ class ChartWidget extends StatelessWidget { final xPos = ((spot.x - minX) / (maxX - minX)) * chartWidth; final yPos = (1 - - (spot.y - chartMinY) / - (chartMaxY - chartMinY)) * + (spot.y - chartMinY) / + (chartMaxY - chartMinY)) * chartHeight; // Prevent label from going outside on the left double adjustedLeft = math.max(0, xPos - 30); return Stack(children: [ Positioned( left: - adjustedLeft, // fine-tune horizontal position + adjustedLeft, // fine-tune horizontal position top: yPos - 60, // fine-tune vertical position child: Text( formatNumber(spot.y), @@ -3960,7 +3961,7 @@ class ChartWidget extends StatelessWidget { style: TextStyle( fontSize: 14, fontFamily: - context.translate('Roboto', 'NotoKufi'), + context.translate('Roboto', 'NotoKufi'), ), ), ], @@ -3974,48 +3975,48 @@ class ChartWidget extends StatelessWidget { ), ); - // case 'd_chart_grouped_bar_horizantal': - // return DChartBar( - // vertical: false, // <--- Important: rotate the chart - // barGroupingType: BarGroupingType.grouped, - // data: const [ - // { - // 'id': 'Product A', - // 'data': [ - // {'domain': 'Jan', 'measure': 30}, - // {'domain': 'Feb', 'measure': 50}, - // {'domain': 'Mar', 'measure': 40}, - // ], - // }, - // { - // 'id': 'Product B', - // 'data': [ - // {'domain': 'Jan', 'measure': 20}, - // {'domain': 'Feb', 'measure': 20}, - // {'domain': 'Mar', 'measure': 35}, - // ], - // }, - // { - // 'id': 'Product C', - // 'data': [ - // {'domain': 'Jan', 'measure': 0}, - // {'domain': 'Feb', 'measure': 25}, - // {'domain': 'Mar', 'measure': 45}, - // ], - // }, - // ], - // groupList: const [ - // {'id': 'Product A', 'color': Colors.orange}, - // {'id': 'Product B', 'color': Colors.deepOrange}, - // {'id': 'Product C', 'color': Colors.pinkAccent}, - // ], - // barValue: (barData, index) => '${barData['measure']}', - // barLabelPosition: BarLabelPosition.outside, - // domainLabelPaddingToAxisLine: 16, - // measureLabelPaddingToAxisLine: 16, - // groupSeparatorWidth: 14, - // barLabelFontSize: 12, - // ); + // case 'd_chart_grouped_bar_horizantal': + // return DChartBar( + // vertical: false, // <--- Important: rotate the chart + // barGroupingType: BarGroupingType.grouped, + // data: const [ + // { + // 'id': 'Product A', + // 'data': [ + // {'domain': 'Jan', 'measure': 30}, + // {'domain': 'Feb', 'measure': 50}, + // {'domain': 'Mar', 'measure': 40}, + // ], + // }, + // { + // 'id': 'Product B', + // 'data': [ + // {'domain': 'Jan', 'measure': 20}, + // {'domain': 'Feb', 'measure': 20}, + // {'domain': 'Mar', 'measure': 35}, + // ], + // }, + // { + // 'id': 'Product C', + // 'data': [ + // {'domain': 'Jan', 'measure': 0}, + // {'domain': 'Feb', 'measure': 25}, + // {'domain': 'Mar', 'measure': 45}, + // ], + // }, + // ], + // groupList: const [ + // {'id': 'Product A', 'color': Colors.orange}, + // {'id': 'Product B', 'color': Colors.deepOrange}, + // {'id': 'Product C', 'color': Colors.pinkAccent}, + // ], + // barValue: (barData, index) => '${barData['measure']}', + // barLabelPosition: BarLabelPosition.outside, + // domainLabelPaddingToAxisLine: 16, + // measureLabelPaddingToAxisLine: 16, + // groupSeparatorWidth: 14, + // barLabelFontSize: 12, + // ); default: return Center(child: Text('Unknown chart type')); } @@ -4155,11 +4156,11 @@ class ChartWidget extends StatelessWidget { } List lineBarsData( - List filteredData, - Set groupByValues, - String groupByKey, - Map chartBarColors, - ) { + List filteredData, + Set groupByValues, + String groupByKey, + Map chartBarColors, + ) { List lineBars = []; print('LineParsedChartBarColors $chartBarColors'); @@ -4289,13 +4290,13 @@ class ChartWidget extends StatelessWidget { TextSpan( // text: formatNumber(lineBarSpot.y), text: (chartConversion != null && - chartConversion.isNotEmpty && - number_format != null) + chartConversion.isNotEmpty && + number_format != null) ? formatNumberConversion( - lineBarSpot.y, - chartConversion, - number_format, - ) + lineBarSpot.y, + chartConversion, + number_format, + ) : formatNumber(lineBarSpot.y), // text: ' ${lineBarSpot.y}', // Keep the value white style: TextStyle( @@ -4403,7 +4404,7 @@ class ChartWidget extends StatelessWidget { double findClosest(double value, Set values) { return values.reduce( - (a, b) => (value - a).abs() < (value - b).abs() ? a : b, + (a, b) => (value - a).abs() < (value - b).abs() ? a : b, ); } @@ -4466,7 +4467,7 @@ class ChartWidget extends StatelessWidget { if (value % 1000000000000 == 0) { // Only multiples of 1T formattedValue = - '${(value / 1000000000000).toStringAsFixed(0)}T'; + '${(value / 1000000000000).toStringAsFixed(0)}T'; } } else if (value >= 1000000000) { // Billions (B) @@ -4606,10 +4607,10 @@ class ChartWidget extends StatelessWidget { } List _generateBarGroups( - BuildContext context, - dynamic chartData, - String groupByKey, - ) { + BuildContext context, + dynamic chartData, + String groupByKey, + ) { Map> groupedData = {}; print('flStackedBar3'); // Group data by `group_by` and `TIME_PERIOD`, accumulating the values for each group and year @@ -4690,7 +4691,7 @@ class ChartWidget extends StatelessWidget { // width: barWidth, borderRadius: BorderRadius.zero, color: - Colors.black, // This will act as a container for stacked items + Colors.black, // This will act as a container for stacked items ), ], ); @@ -4828,9 +4829,9 @@ class ChartWidget extends StatelessWidget { } List _buildHorizontalRotateBarGroups( - dynamic chartData, - Set groupByValues, - ) { + dynamic chartData, + Set groupByValues, + ) { String groupByKeyValueData; if (chartData['chart_type_json']['chart_type'] == 'bar_chart_horizontal' || @@ -4883,11 +4884,11 @@ class ChartWidget extends StatelessWidget { colorIndex++; } else if (chartData['dataset'] == 'cropsk') { barColor = - uniqueColorsForThree[colorIndex % uniqueColorsForThree.length]; + uniqueColorsForThree[colorIndex % uniqueColorsForThree.length]; colorIndex++; } else if (chartData['dataset'] == 'oil_and_gas') { barColor = - uniqueColorsForFour[colorIndex % uniqueColorsForFour.length]; + uniqueColorsForFour[colorIndex % uniqueColorsForFour.length]; colorIndex++; } else { barColor = uniqueColors[colorIndex % uniqueColors.length]; @@ -4916,7 +4917,7 @@ class ChartWidget extends StatelessWidget { barRods: barRods, showingTooltipIndicators: List.generate( barRods.length, - (index) => index, + (index) => index, ), ), ); @@ -4928,8 +4929,7 @@ class ChartWidget extends StatelessWidget { List _buildHorizontalRotateBarGroupsBarColors( dynamic chartData, Set groupByValues, - Map chartBarColors - ) { + Map chartBarColors) { String groupByKeyValueData1; if (chartData['chart_type_json']['chart_type'] == 'bar_chart_horizontal' || @@ -4994,7 +4994,7 @@ class ChartWidget extends StatelessWidget { Color barColor; if (chartData['dataset'] == 'health_services') { barColor = uniqueColorsForTwo[ - colorIndex % 2]; // Alternate between two colors + colorIndex % 2]; // Alternate between two colors colorIndex++; // Update index for next bar } else { print('check fl chart'); @@ -5018,7 +5018,7 @@ class ChartWidget extends StatelessWidget { barRods: barRods, showingTooltipIndicators: List.generate( barRods.length, - (index) => index, + (index) => index, ), ), ); @@ -5116,7 +5116,6 @@ class ChartWidget extends StatelessWidget { // return barGroups; // } - /// End horizontal rotate and fl_multi_bar bar @override @@ -5170,7 +5169,6 @@ class ChartWidget extends StatelessWidget { // ); // } - Widget _buildChartLegend( Map> groupedCrops, Map parsedChartBarColors, @@ -5178,7 +5176,7 @@ Widget _buildChartLegend( BuildContext context) { // Extract unique crop types Set uniqueCropTypes = - groupedCrops.values.expand((list) => list).toSet(); + groupedCrops.values.expand((list) => list).toSet(); print('HorizontalLegends2 -$uniqueCropTypes'); print('HorizontalLegends -$parsedChartBarColors'); @@ -5190,10 +5188,10 @@ Widget _buildChartLegend( children: uniqueCropTypes.map((cropType) { // Color cropColor = parsedChartBarColors[cropType] ?? Colors.grey; // Fetch color for each crop type int index = uniqueCropTypes.toList().indexOf( - cropType, - ); // Get index for cycling colors + cropType, + ); // Get index for cycling colors Color cropColor = parsedChartBarColors.isNotEmpty && - parsedChartBarColors.containsKey(cropType) + parsedChartBarColors.containsKey(cropType) ? parsedChartBarColors[cropType]! : uniqueColors[index % uniqueColors.length]; @@ -5280,4 +5278,4 @@ class ChartData { final String? x; final double y; final DateTime? xDateTime; -} \ No newline at end of file +} diff --git a/pubspec.lock b/pubspec.lock index 4c3a2682..917d85bd 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -516,10 +516,10 @@ packages: dependency: transitive description: name: file_selector_macos - sha256: "44f24d102e368370951b98ffe86c7325b38349e634578312976607d28cc6d747" + sha256: "19124ff4a3d8864fdc62072b6a2ef6c222d55a3404fe14893a3c02744907b60c" url: "https://pub.dev" source: hosted - version: "0.9.4+6" + version: "0.9.4+4" file_selector_platform_interface: dependency: transitive description: @@ -654,10 +654,10 @@ packages: dependency: transitive description: name: flutter_plugin_android_lifecycle - sha256: "306f0596590e077338312f38837f595c04f28d6cdeeac392d3d74df2f0003687" + sha256: c2fe1001710127dfa7da89977a08d591398370d099aacdaa6d44da7eb14b8476 url: "https://pub.dev" source: hosted - version: "2.0.32" + version: "2.0.31" flutter_rating_bar: dependency: "direct main" description: @@ -832,18 +832,18 @@ packages: dependency: transitive description: name: google_sign_in_android - sha256: eff4ad55abb5de68ef85f1eb9c372638e9b45bea14871cbe8fa8fa78c366335f + sha256: "799165f4c0621ed233bccdded4c2e92739bc1fe73e970163b2f7493b301adad3" url: "https://pub.dev" source: hosted - version: "7.2.5" + version: "7.2.1" google_sign_in_ios: dependency: transitive description: name: google_sign_in_ios - sha256: aee8bb29484611a37607849175a2009d423de6bd7c129326c69fd7068f0b6ed7 + sha256: d9d80f953a244a099a40df1ff6aadc10ee375e6a098bbd5d55be332ce26db18c url: "https://pub.dev" source: hosted - version: "6.2.4" + version: "6.2.1" google_sign_in_platform_interface: dependency: transitive description: @@ -952,10 +952,10 @@ packages: dependency: transitive description: name: image_picker_android - sha256: a1cd1584fae64f6ecca63113fd5450e3483c097cc05e43a2f073330f62adcabe + sha256: "28f3987ca0ec702d346eae1d90eda59603a2101b52f1e234ded62cff1d5cfa6e" url: "https://pub.dev" source: hosted - version: "0.8.13+8" + version: "0.8.13+1" image_picker_for_web: dependency: transitive description: @@ -968,10 +968,10 @@ packages: dependency: transitive description: name: image_picker_ios - sha256: "997d100ce1dda5b1ba4085194c5e36c9f8a1fb7987f6a36ab677a344cd2dc986" + sha256: eb06fe30bab4c4497bad449b66448f50edcc695f1c59408e78aa3a8059eb8f0e url: "https://pub.dev" source: hosted - version: "0.8.13+2" + version: "0.8.13" image_picker_linux: dependency: transitive description: @@ -984,10 +984,10 @@ packages: dependency: transitive description: name: image_picker_macos - sha256: "86f0f15a309de7e1a552c12df9ce5b59fe927e71385329355aec4776c6a8ec91" + sha256: d58cd9d67793d52beefd6585b12050af0a7663c0c2a6ece0fb110a35d6955e04 url: "https://pub.dev" source: hosted - version: "0.2.2+1" + version: "0.2.2" image_picker_platform_interface: dependency: transitive description: @@ -1080,26 +1080,26 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "33e2e26bdd85a0112ec15400c8cbffea70d0f9c3407491f672a2fad47915e2de" + sha256: "6bb818ecbdffe216e81182c2f0714a2e62b593f4a4f13098713ff1685dfb6ab0" url: "https://pub.dev" source: hosted - version: "11.0.2" + version: "10.0.9" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "1dbc140bb5a23c75ea9c4811222756104fbcd1a27173f0c34ca01e16bea473c1" + sha256: f8b613e7e6a13ec79cfdc0e97638fddb3ab848452eff057653abd3edba760573 url: "https://pub.dev" source: hosted - version: "3.0.10" + version: "3.0.9" leak_tracker_testing: dependency: transitive description: name: leak_tracker_testing - sha256: "8d5a2d49f4a66b49744b23b018848400d23e54caf9463f4eb20df3eb8acb2eb1" + sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3" url: "https://pub.dev" source: hosted - version: "3.0.2" + version: "3.0.1" lints: dependency: transitive description: @@ -1248,18 +1248,18 @@ packages: dependency: transitive description: name: path_provider_android - sha256: "95c68a74d3cab950fd0ed8073d9fab15c1c06eb1f3eec68676e87aabc9ecee5a" + sha256: "3b4c1fc3aa55ddc9cd4aa6759984330d5c8e66aa7702a6223c61540dc6380c37" url: "https://pub.dev" source: hosted - version: "2.2.21" + version: "2.2.19" path_provider_foundation: dependency: transitive description: name: path_provider_foundation - sha256: "97390a0719146c7c3e71b6866c34f1cde92685933165c1c671984390d2aca776" + sha256: "16eef174aacb07e09c351502740fa6254c165757638eba1e9116b0a781201bbd" url: "https://pub.dev" source: hosted - version: "2.4.4" + version: "2.4.2" path_provider_linux: dependency: transitive description: @@ -1455,18 +1455,18 @@ packages: dependency: transitive description: name: shared_preferences_android - sha256: "07d552dbe8e71ed720e5205e760438ff4ecfb76ec3b32ea664350e2ca4b0c43b" + sha256: bd14436108211b0d4ee5038689a56d4ae3620fd72fd6036e113bf1345bc74d9e url: "https://pub.dev" source: hosted - version: "2.4.16" + version: "2.4.13" shared_preferences_foundation: dependency: transitive description: name: shared_preferences_foundation - sha256: "4e7eaffc2b17ba398759f1151415869a34771ba11ebbccd1b0145472a619a64f" + sha256: "6a52cfcdaeac77cad8c97b539ff688ccfc458c007b4db12be584fbe5c0e49e03" url: "https://pub.dev" source: hosted - version: "2.5.6" + version: "2.5.4" shared_preferences_linux: dependency: transitive description: @@ -1603,10 +1603,10 @@ packages: dependency: transitive description: name: test_api - sha256: "522f00f556e73044315fa4585ec3270f1808a4b186c936e612cab0b565ff1e00" + sha256: fb31f383e2ee25fbbfe06b40fe21e1e458d14080e3c67e7ba0acfde4df4e0bbd url: "https://pub.dev" source: hosted - version: "0.7.6" + version: "0.7.4" the_validator: dependency: "direct main" description: @@ -1659,18 +1659,18 @@ packages: dependency: transitive description: name: url_launcher_android - sha256: dff5e50339bf30b06d7950b50fda58164d3d8c40042b104ed041ddc520fbff28 + sha256: "81777b08c498a292d93ff2feead633174c386291e35612f8da438d6e92c4447e" url: "https://pub.dev" source: hosted - version: "6.3.25" + version: "6.3.20" url_launcher_ios: dependency: transitive description: name: url_launcher_ios - sha256: cfde38aa257dae62ffe79c87fab20165dfdf6988c1d31b58ebf59b9106062aad + sha256: d80b3f567a617cb923546034cc94bfe44eb15f989fe670b37f26abdb9d939cb7 url: "https://pub.dev" source: hosted - version: "6.3.6" + version: "6.3.4" url_launcher_linux: dependency: transitive description: @@ -1683,10 +1683,10 @@ packages: dependency: transitive description: name: url_launcher_macos - sha256: "368adf46f71ad3c21b8f06614adb38346f193f3a59ba8fe9a2fd74133070ba18" + sha256: c043a77d6600ac9c38300567f33ef12b0ef4f4783a2c1f00231d2b1941fea13f url: "https://pub.dev" source: hosted - version: "3.2.5" + version: "3.2.3" url_launcher_platform_interface: dependency: transitive description: @@ -1747,10 +1747,10 @@ packages: dependency: transitive description: name: vector_math - sha256: d530bd74fea330e6e364cda7a85019c434070188383e1cd8d9777ee586914c5b + sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803" url: "https://pub.dev" source: hosted - version: "2.2.0" + version: "2.1.4" video_player: dependency: "direct main" description: @@ -1763,18 +1763,18 @@ packages: dependency: transitive description: name: video_player_android - sha256: "36913f94430b474c4a9033d59b7552b800e736a8521e7166e84895ddcedd0b03" + sha256: a8dc4324f67705de057678372bedb66cd08572fe7c495605ac68c5f503324a39 url: "https://pub.dev" source: hosted - version: "2.8.19" + version: "2.8.15" video_player_avfoundation: dependency: transitive description: name: video_player_avfoundation - sha256: "6bced1739cf1f96f03058118adb8ac0dd6f96aa1a1a6e526424ab92fd2a6a77d" + sha256: f9a780aac57802b2892f93787e5ea53b5f43cc57dc107bee9436458365be71cd url: "https://pub.dev" source: hosted - version: "2.8.7" + version: "2.8.4" video_player_platform_interface: dependency: transitive description: @@ -1795,10 +1795,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "45caa6c5917fa127b5dbcfbd1fa60b14e583afdc08bfc96dda38886ca252eb60" + sha256: ddfa8d30d89985b96407efce8acbdd124701f96741f2d981ca860662f1c0dc02 url: "https://pub.dev" source: hosted - version: "15.0.2" + version: "15.0.0" watcher: dependency: transitive description: @@ -1872,5 +1872,5 @@ packages: source: hosted version: "3.1.3" sdks: - dart: ">=3.9.0 <4.0.0" - flutter: ">=3.35.0" + dart: ">=3.8.0 <4.0.0" + flutter: ">=3.32.0"