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)
.toList();
for (var item in filterData) {
if (item['filter_key'] == 'TIME_PERIOD') {
// Convert the values to integers, sort them, and convert back to strings
List<int> timePeriodData = item['filter_data']
.map<int>((e) => int.parse(e.toString())) // Convert to int
.toList();
timePeriodData.sort((a, b) => a.compareTo(b)); // Sort numerically
// Optionally, convert sorted integers back to strings if necessary
item['filter_data'] = timePeriodData.map((e) => e.toString()).toList();
}
}
print("FilteringDAtss START1 - $filterData");
print('TABId1 - $tabId');
// for (var item in filterData) {
// if (item['filter_key'] == 'TIME_PERIOD') {
// // Convert the values to integers, sort them, and convert back to strings
// List<int> timePeriodData = item['filter_data']
// .map<int>((e) => int.parse(e.toString())) // Convert to int
// .toList();
// timePeriodData.sort((a, b) => a.compareTo(b)); // Sort numerically
//
// // 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");
setState(() {
@ -2112,6 +2115,8 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
// width: 24,
// height: 24,
// ),
SvgPicture.asset(
UaeNumbersAssetPath.share,
semanticsLabel: 'share',
@ -2625,7 +2630,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
onTap: () {
setState(() {
_activeTabIndex = _tabsData.indexOf(tab);
});
});
_scrollToIndex(_activeTabIndex);
onTabSelected(tab['id']!);
},
@ -2647,4 +2652,4 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
),
);
}
}
}

View File

@ -494,6 +494,7 @@ class ChartWidget extends StatelessWidget {
colorIndex % uniqueColorsLine_trend_2.length];
colorIndex++;
}
print('LnTrnd1');
// Extract all years from the chart data
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
int maxYear = years.reduce((a, b) => a > b ? a : b);
int minYear = maxYear - 5;
@ -521,16 +524,82 @@ class ChartWidget extends StatelessWidget {
int year = int.tryParse(entry['ObsKey']['TIME_PERIOD'] ?? '0') ?? 0;
return year >= minYear && year <= maxYear;
}).toList();
print('LnTrnd2');
Set<double> uniqueXValues = filteredData
.map<double>(
(entry) => double.parse(entry['ObsKey']['TIME_PERIOD']))
// Set<double> uniqueXValues = filteredData
// .map<double>(
// (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();
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
List<LineChartBarData> lineBars =
lineBarsData(filteredData, groupByValues, groupByKey);
print('LnTrnd3');
return Column(children: [
Text(
chartData['chart_heading'] ?? '', // Chart title from data
@ -555,12 +624,17 @@ class ChartWidget extends StatelessWidget {
child: LineChart(LineChartData(
lineTouchData: lineTouchData1(),
gridData: gridData(),
titlesData: titlesData1(uniqueXValues),
// titlesData: titlesData1(uniqueXValues),
titlesData: titlesData1(uniqueXValuesProcessed),
borderData: borderData(),
lineBarsData: lineBars,
minX: uniqueXValues.reduce((a, b) => a < b ? a : b),
maxX: 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),
// minX: uniqueXValuesProcessed.reduce((a, b) => a < b ? a : b),
// maxX: uniqueXValuesProcessed.reduce((a, b) => a > b ? a : b),
))),
Padding(
padding: const EdgeInsets.all(8.0),
child: Wrap(
@ -641,7 +715,7 @@ class ChartWidget extends StatelessWidget {
// Generate line bars for the chart
List<LineChartBarData> lineBars =
lineBarsData(filteredData, groupByValues, groupByKey);
return Column(children: [
Text(
chartData['chart_heading'] ?? '', // Chart title from data
@ -1061,19 +1135,45 @@ class ChartWidget extends StatelessWidget {
String cropKey = chartData['chart_type_json']['x_sub_group'];
// Group crops by CROP_TYPE
Map<String, List<String>> groupedCrops = {};
int touchedGroupIndex = -1;
// 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)) {
groupedCrops[cropType]!.add(crop);
groupedCrops[cropType] = (groupedCrops[cropType]! + [crop]).toSet().toList();
} else {
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: [
Text(
chartData['chart_heading'] ?? '', // Chart title from data
@ -1189,7 +1289,8 @@ class ChartWidget extends StatelessWidget {
} else {
print(
'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');
@ -1754,6 +1855,34 @@ class ChartWidget extends StatelessWidget {
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,
Set<String> groupByValues, String groupByKey) {
List<LineChartBarData> lineBars = [];
@ -1779,14 +1908,66 @@ class ChartWidget extends StatelessWidget {
print('Group-Color Map: $groupColorMap');
// Iterate through each group and generate line data
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
.where((entry) => entry['ObsKey'][groupByKey] == group)
.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']);
return FlSpot(xValue, yValue);
}).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
lineBars.add(
LineChartBarData(
@ -1830,6 +2011,13 @@ class ChartWidget extends StatelessWidget {
}
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(
leftTitles: AxisTitles(
sideTitles: SideTitles(
@ -1840,7 +2028,7 @@ class ChartWidget extends StatelessWidget {
String formattedValue;
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) {
formattedValue = '${(value / 1000000).toStringAsFixed(0)}M';
} else if (value >= 1000) {
@ -1857,7 +2045,7 @@ class ChartWidget extends StatelessWidget {
// Update the last formatted value for the next comparison
_lastFormattedValue = formattedValue;
print('formattedValueLine - $formattedValue');
// print('formattedValueLine - $formattedValue');
return Text(formattedValue, style: TextStyle(fontSize: 10));
}
return const SizedBox.shrink();
@ -1872,9 +2060,19 @@ class ChartWidget extends StatelessWidget {
bottomTitles: AxisTitles(
sideTitles: SideTitles(
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) {
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(
angle: -0.5, // Slight rotation to improve readability
child: Text(
@ -2207,7 +2405,7 @@ double calculateBarWidth(BuildContext context, int totalBars) {
barWidth = availableWidth;
}
// Optional: Add a minimum width constraint if needed
// Optional: Add a minimum width constraint if needed
double minWidth = 10.0; // Example minimum width
if (barWidth < minWidth) {
barWidth = minWidth;
@ -2222,4 +2420,4 @@ class ChartData {
final DateTime? xDateTime;
ChartData({this.x, required this.y, this.xDateTime});
}
}