This commit is contained in:
venbaittech 2025-02-18 09:33:59 +05:30
parent 4917749f65
commit d1bcedd4fe
2 changed files with 238 additions and 35 deletions

View File

@ -1764,18 +1764,21 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
.expand((item) => item) .expand((item) => item)
.toList(); .toList();
for (var item in filterData) { print("FilteringDAtss START1 - $filterData");
if (item['filter_key'] == 'TIME_PERIOD') { print('TABId1 - $tabId');
// Convert the values to integers, sort them, and convert back to strings // for (var item in filterData) {
List<int> timePeriodData = item['filter_data'] // if (item['filter_key'] == 'TIME_PERIOD') {
.map<int>((e) => int.parse(e.toString())) // Convert to int // // Convert the values to integers, sort them, and convert back to strings
.toList(); // List<int> timePeriodData = item['filter_data']
timePeriodData.sort((a, b) => a.compareTo(b)); // Sort numerically // .map<int>((e) => int.parse(e.toString())) // Convert to int
// .toList();
// Optionally, convert sorted integers back to strings if necessary // timePeriodData.sort((a, b) => a.compareTo(b)); // Sort numerically
item['filter_data'] = timePeriodData.map((e) => e.toString()).toList(); //
} // // Optionally, convert sorted integers back to strings if necessary
} // item['filter_data'] = timePeriodData.map((e) => e.toString()).toList();
// }
// }
print('TABId - $tabId');
print("TABFiltered Data: $filterData"); print("TABFiltered Data: $filterData");
setState(() { setState(() {
@ -2112,6 +2115,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
// width: 24, // width: 24,
// height: 24, // height: 24,
// ), // ),
SvgPicture.asset( SvgPicture.asset(
UaeNumbersAssetPath.share, UaeNumbersAssetPath.share,
semanticsLabel: 'share', semanticsLabel: 'share',

View File

@ -494,6 +494,7 @@ class ChartWidget extends StatelessWidget {
colorIndex % uniqueColorsLine_trend_2.length]; colorIndex % uniqueColorsLine_trend_2.length];
colorIndex++; colorIndex++;
} }
print('LnTrnd1');
// Extract all years from the chart data // Extract all years from the chart data
List<int> years = (chartData['response'] as List<dynamic>) List<int> years = (chartData['response'] as List<dynamic>)
@ -511,6 +512,8 @@ class ChartWidget extends StatelessWidget {
); );
} }
print('LnTrnd1.2');
// Find the maximum year and calculate the range for the last 5 years // Find the maximum year and calculate the range for the last 5 years
int maxYear = years.reduce((a, b) => a > b ? a : b); int maxYear = years.reduce((a, b) => a > b ? a : b);
int minYear = maxYear - 5; int minYear = maxYear - 5;
@ -521,16 +524,82 @@ class ChartWidget extends StatelessWidget {
int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0; int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
return year >= minYear && year <= maxYear; return year >= minYear && year <= maxYear;
}).toList(); }).toList();
print('LnTrnd2');
Set<double> uniqueXValues = filteredData // Set<double> uniqueXValues = filteredData
.map<double>( // .map<double>(
(entry) => double.parse(entry['ObsKey']['TIME_PERIOD'])) // (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']))
// .toSet();
Set<String> uniqueXValues = filteredData
.map<String>((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
}
// 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(); .toSet();
print("Unique X Values: $uniqueXValues");
double parseTimePeriod(String timePeriod) {
// Match formats
if (RegExp(r'^\d{4}$').hasMatch(timePeriod)) {
return double.parse(timePeriod); // Year-only (2019 2019.0)
} else if (RegExp(r'^\d{4}-\d{2}$').hasMatch(timePeriod)) {
return double.parse(timePeriod.replaceAll('-', '.')); // Year-Month (2019-11 2019.11)
} else if (RegExp(r'^\d{4}-[A-Za-z]{3}$').hasMatch(timePeriod)) {
// Year-MonthAbbr (2019-Nov)
Map<String, int> monthMap = {
'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4,
'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8,
'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12
};
List<String> parts = timePeriod.split('-');
int month = monthMap[parts[1]] ?? 1; // Default to January if unknown
return double.parse('${parts[0]}.$month'); // Convert to format (2019-Nov 2019.11)
}
throw FormatException("Invalid TIME_PERIOD format: $timePeriod");
}
Set<double> uniqueXValuesProcessed = uniqueXValues
.where((value) => value.isNotEmpty) // Remove any empty strings
.map(parseTimePeriod)
.toSet();
print('Processed X Values: $uniqueXValuesProcessed');
print('LnTrnd2.1');
// Generate line bars for the chart // Generate line bars for the chart
List<LineChartBarData> lineBars = List<LineChartBarData> lineBars =
lineBarsData(filteredData, groupByValues, groupByKey); lineBarsData(filteredData, groupByValues, groupByKey);
print('LnTrnd3');
return Column(children: [ return Column(children: [
Text( Text(
chartData['chart_heading'] ?? '', // Chart title from data chartData['chart_heading'] ?? '', // Chart title from data
@ -555,11 +624,16 @@ class ChartWidget extends StatelessWidget {
child: LineChart(LineChartData( child: LineChart(LineChartData(
lineTouchData: lineTouchData1(), lineTouchData: lineTouchData1(),
gridData: gridData(), gridData: gridData(),
titlesData: titlesData1(uniqueXValues), // titlesData: titlesData1(uniqueXValues),
titlesData: titlesData1(uniqueXValuesProcessed),
borderData: borderData(), borderData: borderData(),
lineBarsData: lineBars, lineBarsData: lineBars,
minX: uniqueXValues.reduce((a, b) => a < b ? a : b), // minX: uniqueXValues.reduce((a, b) => a < b ? a : b),
maxX: uniqueXValues.reduce((a, b) => a > b ? a : b), // maxX: uniqueXValues.reduce((a, b) => a > b ? a : b),
// minX: uniqueXValuesProcessed.reduce((a, b) => a < b ? a : b),
// maxX: uniqueXValuesProcessed.reduce((a, b) => a > b ? a : b),
))), ))),
Padding( Padding(
padding: const EdgeInsets.all(8.0), padding: const EdgeInsets.all(8.0),
@ -1061,19 +1135,45 @@ class ChartWidget extends StatelessWidget {
String cropKey = chartData['chart_type_json']['x_sub_group']; String cropKey = chartData['chart_type_json']['x_sub_group'];
// Group crops by CROP_TYPE // Group crops by CROP_TYPE
Map<String, List<String>> groupedCrops = {}; Map<String, List<String>> groupedCrops = {};
int touchedGroupIndex = -1; int touchedGroupIndex = -1;
// Iterate over the chartData to group crops by CROP_TYPE // Iterate over the chartData to group crops by CROP_TYPE
for (var item in chartData['response']) {
String crop, cropType;
crop = item['ObsKey'][cropKey];
cropType = item['ObsKey'][groupByKey];
for (var item in chartData['response']) {
// print("MultiBArRaw item: $item");
String crop = item['ObsKey'][cropKey];
String cropType = item['ObsKey'][groupByKey];
// Use a Set to avoid duplicates
if (groupedCrops.containsKey(cropType)) { if (groupedCrops.containsKey(cropType)) {
groupedCrops[cropType]!.add(crop); groupedCrops[cropType] = (groupedCrops[cropType]! + [crop]).toSet().toList();
} else { } else {
groupedCrops[cropType] = [crop]; groupedCrops[cropType] = [crop];
} }
} }
print('Unique groupedCrops: $groupedCrops');
// for (var item in chartData['response']) {
// String crop, cropType;
// crop = item['ObsKey'][cropKey];
// cropType = item['ObsKey'][groupByKey];
//
// if (groupedCrops.containsKey(cropType)) {
// groupedCrops[cropType]!.add(crop);
// } else {
// groupedCrops[cropType] = [crop];
// }
// }
//
// print('groupedCropsflmutli- $groupedCrops');
return Column(children: [ return Column(children: [
Text( Text(
chartData['chart_heading'] ?? '', // Chart title from data chartData['chart_heading'] ?? '', // Chart title from data
@ -1189,7 +1289,8 @@ class ChartWidget extends StatelessWidget {
} else { } else {
print( print(
'Crop is null or index out of bounds for cropType: $cropType and rodIndex: $rodIndex'); 'Crop is null or index out of bounds for cropType: $cropType and rodIndex: $rodIndex');
crop = cropType; // Fallback to cropType // crop = cropType; // Fallback to cropType
crop = (crops != null && crops.isNotEmpty) ? crops.first : cropType;
} }
// print('groupedCrops1: $groupedCrops - $rodIndex'); // print('groupedCrops1: $groupedCrops - $rodIndex');
@ -1754,6 +1855,34 @@ class ChartWidget extends StatelessWidget {
return lineBars; return lineBars;
} }
/// Function to parse TIME_PERIOD into a EXACT value
double parseTimePeriod(String timePeriod) {
// Match formats
if (RegExp(r'^\d{4}$').hasMatch(timePeriod)) {
// Format: Year-only (e.g., "2020")
return double.parse(timePeriod); // Year as a double (2020 2020.0)
} else if (RegExp(r'^\d{4}-\d{2}$').hasMatch(timePeriod)) {
// Format: Year-Month (e.g., "2020-10")
return double.parse(timePeriod.replaceAll('-', '.')); // Convert "2020-10" 2020.10
} else if (RegExp(r'^\d{4}-[A-Za-z]{3}$').hasMatch(timePeriod)) {
// Format: Year-MonthAbbr (e.g., "2020-Oct")
Map<String, int> monthMap = {
'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4,
'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8,
'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12
};
List<String> parts = timePeriod.split('-');
int month = monthMap[parts[1]] ?? 1; // Default to January if unknown
return double.parse('${parts[0]}.$month'); // Convert "2020-Oct" 2020.10
}
// Throw an error for unsupported formats
throw FormatException("Invalid TIME_PERIOD format: $timePeriod");
}
List<LineChartBarData> lineBarsData(List<dynamic> filteredData, List<LineChartBarData> lineBarsData(List<dynamic> filteredData,
Set<String> groupByValues, String groupByKey) { Set<String> groupByValues, String groupByKey) {
List<LineChartBarData> lineBars = []; List<LineChartBarData> lineBars = [];
@ -1779,14 +1908,66 @@ class ChartWidget extends StatelessWidget {
print('Group-Color Map: $groupColorMap'); print('Group-Color Map: $groupColorMap');
// Iterate through each group and generate line data // Iterate through each group and generate line data
for (String group in groupByValues) { for (String group in groupByValues) {
print('lineGrp1');
// List<FlSpot> spots = filteredData
// .where((entry) => entry['ObsKey'][groupByKey] == group)
// .map<FlSpot>((entry) {
// print("FindTimePeriod");
// print(entry['ObsKey'][groupByKey]);
// double xValue = double.parse(entry['ObsKey']['TIME_PERIOD']);
// double yValue = double.parse(entry['ObsValue']['Value']);
// return FlSpot(xValue, yValue);
// }).toList();
// List<FlSpot> spots = filteredData
// .where((entry) => entry['ObsKey'][groupByKey] == group)
// .map<FlSpot>((entry) {
// String timePeriod = entry['ObsKey']['TIME_PERIOD'];
// print("FindTimePeriod: $timePeriod");
//
// double xValue = parseTimePeriodToDouble(timePeriod); // Convert to double for graph plotting
// double yValue = double.parse(entry['ObsValue']['Value']);
// print('TimePeriod: $timePeriod, xValue: $xValue, yValue: $yValue');
//
// return FlSpot(xValue, yValue);
// }).toList();
List<FlSpot> spots = filteredData List<FlSpot> spots = filteredData
.where((entry) => entry['ObsKey'][groupByKey] == group) .where((entry) => entry['ObsKey'][groupByKey] == group)
.map<FlSpot>((entry) { .map<FlSpot>((entry) {
double xValue = double.parse(entry['ObsKey']['TIME_PERIOD']); String timePeriod = entry['ObsKey']['TIME_PERIOD'];
print("FindTimePeriod: $timePeriod");
// Use the timePeriod directly as a string for x-axis
double xValue = parseTimePeriod(timePeriod);
double yValue = double.parse(entry['ObsValue']['Value']); double yValue = double.parse(entry['ObsValue']['Value']);
return FlSpot(xValue, yValue); return FlSpot(xValue, yValue);
}).toList(); }).toList();
print('spots - $spots');
// List<FlSpot> spots = filteredData
// .where((entry) => entry['ObsKey'][groupByKey] == group)
// .map<FlSpot>((entry) {
// String timePeriod = entry['ObsKey']['TIME_PERIOD'];
// List<String> parts = timePeriod.split('-'); // Split "2017-01" into ["2017", "01"]
//
// double year = double.parse(parts[0]); // Convert "2017" to 2017.0
// double month = double.parse(parts[1]) / 12; // Convert "01" to 1/12
//
// double xValue = year + month; // E.g., "2017-06" becomes 2017.5
// double yValue = double.parse(entry['ObsValue']['Value']);
//
// return FlSpot(xValue, yValue);
// }).toList();
print('lineGrp2');
// Add a line for this group // Add a line for this group
lineBars.add( lineBars.add(
LineChartBarData( LineChartBarData(
@ -1830,6 +2011,13 @@ class ChartWidget extends StatelessWidget {
} }
FlTitlesData titlesData1(Set<double> xValues) { FlTitlesData titlesData1(Set<double> xValues) {
print('tileDATa1xvalue - $xValues');
double findClosest(double value, Set<double> values) {
return values.reduce((a, b) => (value - a).abs() < (value - b).abs() ? a : b);
}
return FlTitlesData( return FlTitlesData(
leftTitles: AxisTitles( leftTitles: AxisTitles(
sideTitles: SideTitles( sideTitles: SideTitles(
@ -1840,7 +2028,7 @@ class ChartWidget extends StatelessWidget {
String formattedValue; String formattedValue;
if (value % 10 == 0) { if (value % 10 == 0) {
// Check if the value is in the millions or thousands range // Check if the value is in the millions or thousands range
if (value >= 1000000) { if (value >= 1000000) {
formattedValue = '${(value / 1000000).toStringAsFixed(0)}M'; formattedValue = '${(value / 1000000).toStringAsFixed(0)}M';
} else if (value >= 1000) { } else if (value >= 1000) {
@ -1857,7 +2045,7 @@ class ChartWidget extends StatelessWidget {
// Update the last formatted value for the next comparison // Update the last formatted value for the next comparison
_lastFormattedValue = formattedValue; _lastFormattedValue = formattedValue;
print('formattedValueLine - $formattedValue'); // print('formattedValueLine - $formattedValue');
return Text(formattedValue, style: TextStyle(fontSize: 10)); return Text(formattedValue, style: TextStyle(fontSize: 10));
} }
return const SizedBox.shrink(); return const SizedBox.shrink();
@ -1872,9 +2060,19 @@ class ChartWidget extends StatelessWidget {
bottomTitles: AxisTitles( bottomTitles: AxisTitles(
sideTitles: SideTitles( sideTitles: SideTitles(
showTitles: true, showTitles: true,
interval: 10, // Ensure each year is shown only once interval: null,
// interval: 10, // Ensure each year is shown only once
getTitlesWidget: (value, meta) { getTitlesWidget: (value, meta) {
if (xValues.contains(value)) {
print('BtmTiles :-$value');
print('BtmTilesmeta :-$meta');
// if (xValues.contains(value))
double closestValue = findClosest(value, xValues);
if ((closestValue - value).abs() < 0.15)
{
print("Bottomtiles");
print(value);
return Transform.rotate( return Transform.rotate(
angle: -0.5, // Slight rotation to improve readability angle: -0.5, // Slight rotation to improve readability
child: Text( child: Text(