chart changes
This commit is contained in:
parent
bdcdf737a8
commit
a1993712ac
@ -1346,10 +1346,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// If chartFilteredData is empty, print the message
|
// If chartFilteredData is empty, print the message
|
||||||
if (chartFilteredData.isEmpty) {
|
if (chartFilteredData.isEmpty) {
|
||||||
if (kDebugMode) {
|
if (kDebugMode) {
|
||||||
print(
|
print("Selected year: ${selectedFilters.firstWhere((f) => f['filter_key'] == 'TIME_PERIOD',
|
||||||
"Selected year: ${selectedFilters.firstWhere((f) => f['filter_key'] == 'TIME_PERIOD', orElse: () => {
|
orElse: () => {'filter_data': ['Unknown']})['filter_data']} - No data for chart: : $chartHeading");
|
||||||
'filter_data': ['Unknown']
|
|
||||||
})['filter_data']} - No data for chart: : $chartHeading");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Add the complete chart data to the filteredData list
|
// Add the complete chart data to the filteredData list
|
||||||
@ -1372,6 +1371,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
addedChartIds
|
addedChartIds
|
||||||
.add(chart['chart_heading']); // Track by a unique identifier
|
.add(chart['chart_heading']); // Track by a unique identifier
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// List filteredCardData = [];
|
// List filteredCardData = [];
|
||||||
@ -1799,18 +1799,21 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
|
|
||||||
print("FilteringDAtss START1 - $filterData");
|
print("FilteringDAtss START1 - $filterData");
|
||||||
print('TABId1 - $tabId');
|
print('TABId1 - $tabId');
|
||||||
// for (var item in filterData) {
|
|
||||||
// if (item['filter_key'] == 'TIME_PERIOD') {
|
for (var item in filterData) {
|
||||||
// // Convert the values to integers, sort them, and convert back to strings
|
if (item['filter_key'] == 'TIME_PERIOD') {
|
||||||
// List<int> timePeriodData = item['filter_data']
|
// Convert the values to integers, sort them, and convert back to strings
|
||||||
// .map<int>((e) => int.parse(e.toString())) // Convert to int
|
List<int> timePeriodData = item['filter_data']
|
||||||
// .toList();
|
.map<int>((e) => int.parse(e.toString())) // Convert to int
|
||||||
// timePeriodData.sort((a, b) => a.compareTo(b)); // Sort numerically
|
.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();
|
// Optionally, convert sorted integers back to strings if necessary
|
||||||
// }
|
item['filter_data'] = timePeriodData.map((e) => e.toString()).toList();
|
||||||
// }
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
print('TABId - $tabId');
|
print('TABId - $tabId');
|
||||||
|
|
||||||
print("TABFiltered Data: $filterData");
|
print("TABFiltered Data: $filterData");
|
||||||
@ -1927,6 +1930,10 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
});
|
});
|
||||||
double myheight = MediaQuery.of(context).size.height;
|
double myheight = MediaQuery.of(context).size.height;
|
||||||
double mywidth = MediaQuery.of(context).size.width;
|
double mywidth = MediaQuery.of(context).size.width;
|
||||||
|
|
||||||
|
int crossAxisCount = cardData.isNotEmpty ? (cardData.length / 2).ceil().clamp(1, 2) : 1;
|
||||||
|
|
||||||
|
|
||||||
final color =
|
final color =
|
||||||
Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16));
|
Color(int.parse(widget.bgColor.replaceFirst('0x', ''), radix: 16));
|
||||||
return PopScope(
|
return PopScope(
|
||||||
@ -1938,45 +1945,6 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
|
|
||||||
child: BaseScaffold(
|
child: BaseScaffold(
|
||||||
key: _scaffoldKey,
|
key: _scaffoldKey,
|
||||||
// backgroundColor: color,
|
|
||||||
// appBar: AppBar(
|
|
||||||
// backgroundColor: color,
|
|
||||||
// elevation: 0,
|
|
||||||
// actions: [
|
|
||||||
// // IconButton(
|
|
||||||
// // onPressed: () {},
|
|
||||||
// // icon: const Icon(Icons.toggle_off_outlined),
|
|
||||||
// // ),
|
|
||||||
// MyToggle(
|
|
||||||
// // key: toggleKey,
|
|
||||||
// isOn: locale?.languageCode == 'en',
|
|
||||||
// knobTextWhenOn: 'ع',
|
|
||||||
// knobTextWhenOff: 'EN',
|
|
||||||
// pathColorWhenOn: Colors.grey.shade300,
|
|
||||||
// pathColorWhenOff: Colors.grey.shade300,
|
|
||||||
// onTap: () {
|
|
||||||
// ref.read(localeProvider.notifier).toggleLocale();
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// leading: IconButton(
|
|
||||||
// icon: Icon(Icons.arrow_back_ios_new, color: Colors.white),
|
|
||||||
// onPressed: () {
|
|
||||||
// if (widget.keyParam == 'home') {
|
|
||||||
// context.go('/myhomepage');
|
|
||||||
// } else {
|
|
||||||
// context.go('/uaenumbers');
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// title: Text(
|
|
||||||
// context.translate(
|
|
||||||
// 'UAE Numbers',
|
|
||||||
// 'أرقام الإمارات',
|
|
||||||
// ),
|
|
||||||
// style: TextStyle(color: Colors.white),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
title: Text(
|
title: Text(
|
||||||
context.translate(
|
context.translate(
|
||||||
'UAE Numbers',
|
'UAE Numbers',
|
||||||
@ -2035,25 +2003,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
fontWeight: FontWeight.w400,
|
fontWeight: FontWeight.w400,
|
||||||
fontFamily: 'Roboto'),
|
fontFamily: 'Roboto'),
|
||||||
),
|
),
|
||||||
// Row(
|
|
||||||
// mainAxisAlignment: MainAxisAlignment.end,
|
|
||||||
// children: [
|
|
||||||
// IconButton(
|
|
||||||
// onPressed: () {},
|
|
||||||
// icon: Icon(
|
|
||||||
// Icons.bookmark_add_outlined,
|
|
||||||
// color: Colors.white,
|
|
||||||
// size: 40,
|
|
||||||
// )),
|
|
||||||
// IconButton(
|
|
||||||
// onPressed: () {},
|
|
||||||
// icon: Icon(
|
|
||||||
// Icons.share,
|
|
||||||
// color: Colors.white,
|
|
||||||
// size: 30,
|
|
||||||
// )),
|
|
||||||
// ],
|
|
||||||
// ),
|
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
)),
|
)),
|
||||||
@ -2201,6 +2151,15 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
SizedBox(
|
SizedBox(
|
||||||
width: 10), // Horizontal space between items
|
width: 10), // Horizontal space between items
|
||||||
Row(
|
Row(
|
||||||
|
children: [
|
||||||
|
|
||||||
|
GestureDetector(
|
||||||
|
onTap: () {
|
||||||
|
showRightSideModal(
|
||||||
|
context, filterData, chartsData);
|
||||||
|
},
|
||||||
|
|
||||||
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
context.translate(
|
context.translate(
|
||||||
@ -2214,17 +2173,14 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
),
|
),
|
||||||
|
|
||||||
SizedBox(width: 10),
|
SizedBox(width: 10),
|
||||||
GestureDetector(
|
Image.asset(
|
||||||
onTap: () {
|
|
||||||
showRightSideModal(
|
|
||||||
context, filterData, chartsData);
|
|
||||||
},
|
|
||||||
child: Image.asset(
|
|
||||||
UaeNumbersAssetPath.filterUae,
|
UaeNumbersAssetPath.filterUae,
|
||||||
color: Colors.white, // Set color to white
|
color: Colors.white, // Set color to white
|
||||||
width: 21,
|
width: 21,
|
||||||
height: 21,
|
height: 21,
|
||||||
),
|
),
|
||||||
|
],),
|
||||||
|
|
||||||
)
|
)
|
||||||
// IconButton(
|
// IconButton(
|
||||||
// icon: Icon(Icons.filter_alt_outlined,
|
// icon: Icon(Icons.filter_alt_outlined,
|
||||||
@ -2302,32 +2258,26 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
// nonChartData Cards
|
// nonChartData Cards
|
||||||
Padding(
|
Padding(
|
||||||
padding: const EdgeInsets.all(3.34),
|
padding: const EdgeInsets.all(3.34),
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
child: GridView.builder(
|
child: GridView.builder(
|
||||||
key: cardKey,
|
key: cardKey,
|
||||||
itemCount: cardData.length,
|
itemCount: cardData.length,
|
||||||
shrinkWrap: true,
|
shrinkWrap: true,
|
||||||
physics: const NeverScrollableScrollPhysics(),
|
physics: const NeverScrollableScrollPhysics(),
|
||||||
gridDelegate:
|
gridDelegate: SliverGridDelegateWithFixedCrossAxisCount(
|
||||||
SliverGridDelegateWithFixedCrossAxisCount(
|
crossAxisCount:crossAxisCount,
|
||||||
// crossAxisCount:2,
|
// crossAxisCount: cardData.length % 2 == 0 ? 2 : 3,
|
||||||
crossAxisCount:
|
|
||||||
cardData.length % 2 == 0 ? 2 : 3,
|
|
||||||
// crossAxisCount: cardData.length == 2
|
|
||||||
// ? 2
|
|
||||||
// : cardData.length == 3
|
|
||||||
// ? 3
|
|
||||||
// : cardData.length == 4
|
|
||||||
// ? 2
|
|
||||||
// : 3, // Default to 3 if more than 4 items // 2 cards per row
|
|
||||||
crossAxisSpacing: 2,
|
crossAxisSpacing: 2,
|
||||||
|
|
||||||
mainAxisSpacing: 5,
|
mainAxisSpacing: 5,
|
||||||
childAspectRatio: MediaQuery.of(context)
|
childAspectRatio: MediaQuery.of(context)
|
||||||
.size
|
.size
|
||||||
.width /
|
.width /
|
||||||
(MediaQuery.of(context).size.height /
|
(MediaQuery.of(context).size.height /
|
||||||
(cardData.length % 2 == 0
|
(cardData.length % 2 == 0 ? 2 : 2)),
|
||||||
? 2
|
|
||||||
: 1.3)),
|
|
||||||
// childAspectRatio:
|
// childAspectRatio:
|
||||||
// calculateAspectRatio(cardData.length, cardData),
|
// calculateAspectRatio(cardData.length, cardData),
|
||||||
),
|
),
|
||||||
@ -2366,6 +2316,7 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
borderRadius:
|
borderRadius:
|
||||||
BorderRadius.circular(12),
|
BorderRadius.circular(12),
|
||||||
border: Border.all(
|
border: Border.all(
|
||||||
|
|
||||||
color: Color(int.parse(
|
color: Color(int.parse(
|
||||||
(chartScreenData[
|
(chartScreenData[
|
||||||
'border_color'] ??
|
'border_color'] ??
|
||||||
@ -2444,15 +2395,17 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
height: 20.0,
|
height: 20.0,
|
||||||
child: FittedBox(
|
child: FittedBox(
|
||||||
child: Text(
|
child: Text(
|
||||||
'(${response[0]['display_value'] ?? 'NA'})',
|
// '(${response[0]['display_value'] ?? 'NA'})',
|
||||||
// '(${data['firstYear'] ??
|
RegExp(r'\d').hasMatch(response[0]['display_value'] ?? '')
|
||||||
// 'NA'} - ${data['lastYear'] ??
|
? '(${response[0]['display_value'] ?? 'NA'})'
|
||||||
// 'NA'})',
|
: '${response[0]['display_value'] ?? 'NA'}',
|
||||||
style:
|
style:
|
||||||
|
|
||||||
const TextStyle(
|
const TextStyle(
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
color: Colors
|
color: Colors.grey,
|
||||||
.grey),
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -2467,60 +2420,35 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
child: Row(
|
child: Row(
|
||||||
children: [
|
children: [
|
||||||
Text(
|
Text(
|
||||||
response[0][
|
response[0]['value'] ?? 'NA',
|
||||||
'value'] ??
|
|
||||||
'NA',
|
|
||||||
// '${data['roundedAverage'] ??
|
// '${data['roundedAverage'] ??
|
||||||
// 'NA'}',
|
// 'NA'}',
|
||||||
style: TextStyle(
|
style:
|
||||||
fontSize: 20,
|
TextStyle(
|
||||||
|
fontSize: 18,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight
|
FontWeight.w800,
|
||||||
.w900,
|
color: response[0]['calculation'] == 'different'
|
||||||
color: response[0]
|
? _getColorFromHex(response[0]['font_color'])
|
||||||
[
|
: const Color(0xFF90B0D5),
|
||||||
'calculation'] ==
|
|
||||||
'different'
|
|
||||||
? _getColorFromHex(
|
|
||||||
response[0]
|
|
||||||
[
|
|
||||||
'font_color'])
|
|
||||||
: const Color(
|
|
||||||
0xFF90B0D5),
|
|
||||||
// color: Color(
|
// color: Color(
|
||||||
// 0xFF90B0D5),
|
// 0xFF90B0D5),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
const SizedBox(
|
const SizedBox(width: 1), // Space between text and icon
|
||||||
width:
|
if (response[0]['calculation'] == 'different') ...[
|
||||||
1), // Space between text and icon
|
if (response[0]['font_color'] == '#D83731')
|
||||||
if (response[0][
|
const Icon(Icons.arrow_downward, color: Colors.red, size: 20)
|
||||||
'calculation'] ==
|
else if (response[0]['font_color'] == '#11AF22')
|
||||||
'different') ...[
|
const Icon(Icons.arrow_upward, color: Colors.green, size: 20),
|
||||||
if (response[0][
|
|
||||||
'font_color'] ==
|
|
||||||
'#D83731')
|
|
||||||
const Icon(
|
|
||||||
Icons
|
|
||||||
.arrow_downward,
|
|
||||||
color: Colors
|
|
||||||
.red,
|
|
||||||
size: 22)
|
|
||||||
else if (response[
|
|
||||||
0][
|
|
||||||
'font_color'] ==
|
|
||||||
'#11AF22')
|
|
||||||
const Icon(
|
|
||||||
Icons
|
|
||||||
.arrow_upward,
|
|
||||||
color: Colors
|
|
||||||
.green,
|
|
||||||
size: 22),
|
|
||||||
],
|
],
|
||||||
],
|
],
|
||||||
|
|
||||||
|
),
|
||||||
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
@ -2608,12 +2536,16 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
),
|
),
|
||||||
const SizedBox(height: 1),
|
const SizedBox(height: 1),
|
||||||
Text(
|
Text(
|
||||||
'(${response[0]['display_value'] ?? 'NA'})',
|
// '(${response[0]['display_value'] ?? 'NA'})',
|
||||||
|
|
||||||
|
RegExp(r'\d').hasMatch(response[0]['display_value'] ?? '')
|
||||||
|
? '(${response[0]['display_value'] ?? 'NA'})'
|
||||||
|
: '${response[0]['display_value'] ?? 'NA'}',
|
||||||
|
|
||||||
// '(${data['lastYear'] ?? 'NA'})',
|
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 10,
|
fontSize: 10,
|
||||||
color: Colors.grey),
|
color: Colors.grey,
|
||||||
|
overflow: TextOverflow.ellipsis,),
|
||||||
),
|
),
|
||||||
const SizedBox(height: 1),
|
const SizedBox(height: 1),
|
||||||
Flexible(
|
Flexible(
|
||||||
@ -2632,14 +2564,9 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
fontSize: 18,
|
fontSize: 18,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w900,
|
FontWeight.w900,
|
||||||
color: response[0][
|
color: response[0]['calculation'] == 'different'
|
||||||
'calculation'] ==
|
? _getColorFromHex(response[0]['font_color'])
|
||||||
'different'
|
: const Color(0xFF90B0D5),
|
||||||
? _getColorFromHex(
|
|
||||||
response[0][
|
|
||||||
'font_color'])
|
|
||||||
: const Color(
|
|
||||||
0xFF90B0D5),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
@ -2666,26 +2593,26 @@ class _ChartScreen1State extends ConsumerState<ChartScreen1> {
|
|||||||
fontSize: 14,
|
fontSize: 14,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w600,
|
FontWeight.w600,
|
||||||
color: response[1][
|
|
||||||
'calculation'] ==
|
color: response[1]['calculation'] == 'different'
|
||||||
'different'
|
? _getColorFromHex(response[0]['font_color'])
|
||||||
? _getColorFromHex(
|
: const Color(0xFFD83731),
|
||||||
response[0][
|
|
||||||
'font_color'])
|
|
||||||
: const Color(
|
|
||||||
0xFFD83731),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
Text(
|
Text(
|
||||||
'(${response[1]['display_value'] ?? 'NA'})',
|
// '(${response[1]['display_value'] ?? 'NA'})',
|
||||||
// '(${data['secondLastYear'] ?? 'NA'})',
|
RegExp(r'\d').hasMatch(response[1]['display_value'] ?? '')
|
||||||
|
? '(${response[1]['display_value'] ?? 'NA'})'
|
||||||
|
: '${response[1]['display_value'] ?? 'NA'}',
|
||||||
style: const TextStyle(
|
style: const TextStyle(
|
||||||
fontSize: 9,
|
fontSize: 9,
|
||||||
fontWeight:
|
fontWeight:
|
||||||
FontWeight.w500,
|
FontWeight.w500,
|
||||||
color: Colors.grey),
|
color: Colors.grey,
|
||||||
|
overflow: TextOverflow.ellipsis,),
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
),
|
),
|
||||||
|
|||||||
@ -49,34 +49,22 @@ class ChartWidget extends StatelessWidget {
|
|||||||
List<PieChartSectionData> parsePieChartData(
|
List<PieChartSectionData> parsePieChartData(
|
||||||
dynamic chartData,
|
dynamic chartData,
|
||||||
double totalValue,
|
double totalValue,
|
||||||
// String totalValue,
|
|
||||||
int? touchedIndex,
|
int? touchedIndex,
|
||||||
) {
|
) {
|
||||||
debugPrint('Chart Data: ${jsonEncode(chartData)}');
|
debugPrint('Chart Data: ${jsonEncode(chartData)}');
|
||||||
|
|
||||||
|
|
||||||
return chartData['response']
|
return chartData['response']
|
||||||
.asMap()
|
.asMap()
|
||||||
.entries
|
.entries
|
||||||
.map<PieChartSectionData>((entry) {
|
.map<PieChartSectionData>((entry) {
|
||||||
int index = entry.key;
|
int index = entry.key;
|
||||||
|
|
||||||
print('piePArse');
|
|
||||||
|
|
||||||
var data = entry.value;
|
var data = entry.value;
|
||||||
// double value = double.tryParse(data['ObsValue']['Value']) ?? 0.0;
|
|
||||||
// double value = (data['ObsValue']['Value'] is double)
|
|
||||||
// ? data['ObsValue']['Value']
|
|
||||||
// : (data['ObsValue']['Value'] is int)
|
|
||||||
// ? (data['ObsValue']['Value'] as int).toDouble()
|
|
||||||
// : 0.0;
|
|
||||||
|
|
||||||
// Handle different types: int, double, and String
|
// Handle different types: int, double, and String
|
||||||
double value = 0.0;
|
double value = 0.0;
|
||||||
|
|
||||||
var rawValue = data['ObsValue']['Value'];
|
var rawValue = data['ObsValue']['Value'];
|
||||||
|
|
||||||
print('Raw Value: $rawValue (Type: ${rawValue.runtimeType})');
|
|
||||||
|
|
||||||
if (rawValue is String) {
|
if (rawValue is String) {
|
||||||
value = double.tryParse(rawValue) ?? 0.0;
|
value = double.tryParse(rawValue) ?? 0.0;
|
||||||
} else if (rawValue is int) {
|
} else if (rawValue is int) {
|
||||||
@ -87,24 +75,8 @@ class ChartWidget extends StatelessWidget {
|
|||||||
print('Unexpected Type for ObsValue[Value]: ${rawValue.runtimeType}');
|
print('Unexpected Type for ObsValue[Value]: ${rawValue.runtimeType}');
|
||||||
}
|
}
|
||||||
|
|
||||||
// if (data['ObsValue']['Value'] is String) {
|
|
||||||
// value = double.tryParse(data['ObsValue']['Value']) ?? 0.0; // Parse string to double
|
|
||||||
// } else if (data['ObsValue']['Value'] is int) {
|
|
||||||
// value = (data['ObsValue']['Value'] as int).toDouble(); // Convert int to double
|
|
||||||
// } else if (data['ObsValue']['Value'] is double) {
|
|
||||||
// value = data['ObsValue']['Value']; // Already a double
|
|
||||||
// }
|
|
||||||
|
|
||||||
print('piePArse1 - $value');
|
|
||||||
// double percentage = (value / totalValue) * 100;
|
// double percentage = (value / totalValue) * 100;
|
||||||
double percentage = (totalValue > 0) ? (value / totalValue) * 100 : 0.0;
|
double percentage = (totalValue > 0) ? (value / totalValue) * 100 : 0.0;
|
||||||
if (kDebugMode) {
|
|
||||||
print('percentage- $percentage');
|
|
||||||
print('Total Value: $totalValue');
|
|
||||||
}
|
|
||||||
|
|
||||||
debugPrint('debug Total Value- $totalValue');
|
|
||||||
debugPrint('debug percentage- $percentage');
|
|
||||||
bool isTouched = index == touchedIndex;
|
bool isTouched = index == touchedIndex;
|
||||||
|
|
||||||
return PieChartSectionData(
|
return PieChartSectionData(
|
||||||
@ -119,9 +91,11 @@ class ChartWidget extends StatelessWidget {
|
|||||||
fontWeight: FontWeight.bold,
|
fontWeight: FontWeight.bold,
|
||||||
color: Colors.black,
|
color: Colors.black,
|
||||||
// color: Colors.white,
|
// color: Colors.white,
|
||||||
|
|
||||||
),
|
),
|
||||||
titlePositionPercentageOffset: 1.3,
|
titlePositionPercentageOffset: 1.3,
|
||||||
);
|
);
|
||||||
|
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -150,32 +124,28 @@ class ChartWidget extends StatelessWidget {
|
|||||||
data: TooltipThemeData(
|
data: TooltipThemeData(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.blueGrey[800], // Change background color
|
color: Colors.blueGrey[800], // Change background color
|
||||||
borderRadius:
|
borderRadius: BorderRadius.circular(8), // Optional: rounded corners
|
||||||
BorderRadius.circular(8), // Optional: rounded corners
|
|
||||||
),
|
),
|
||||||
textStyle: TextStyle(color: Colors.white), // Change text color
|
textStyle: TextStyle(color: Colors.white), // Change text color
|
||||||
),
|
),
|
||||||
child: Tooltip(
|
child: Tooltip(
|
||||||
message: title, // Full text on hover
|
message: title, // Full text on hover
|
||||||
child: ConstrainedBox(
|
child: ConstrainedBox( // Constrain width to allow wrapping
|
||||||
// Constrain width to allow wrapping
|
|
||||||
constraints: BoxConstraints(maxWidth: 100),
|
constraints: BoxConstraints(maxWidth: 100),
|
||||||
child: Text(
|
child: Text(
|
||||||
title,
|
title,
|
||||||
style: TextStyle(
|
style: TextStyle(fontSize: 12,),
|
||||||
fontSize: 12,
|
|
||||||
),
|
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
overflow:
|
overflow: TextOverflow.ellipsis, // Ensures text doesn't overflow
|
||||||
TextOverflow.ellipsis, // Ensures text doesn't overflow
|
|
||||||
),
|
|
||||||
),
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
),),
|
||||||
SizedBox(width: 5),
|
SizedBox(width: 5),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
|
|
||||||
}).toList();
|
}).toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -287,28 +257,12 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
case 'pie_chart':
|
case 'pie_chart':
|
||||||
double totalValue = chartData['response'].map<double>((entry) {
|
double totalValue = chartData['response']
|
||||||
|
.map<double>((entry) {
|
||||||
var value = entry['ObsValue']['Value'];
|
var value = entry['ObsValue']['Value'];
|
||||||
print(
|
// print('Processing value: $value, type: ${value.runtimeType}');
|
||||||
'Processing value: $value, type: ${value.runtimeType}'); // Debug each value
|
return (value is num) ? value.toDouble() : value is String ? double.tryParse(value) ?? 0.0 : 0.0;
|
||||||
print(value is int
|
|
||||||
? value.toDouble()
|
|
||||||
: value is String
|
|
||||||
? double.tryParse(value) ?? 0.0
|
|
||||||
: 0.0);
|
|
||||||
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);
|
||||||
// List<String> totalValues = chartData['response']
|
|
||||||
// .map<String>((entry) {
|
|
||||||
// var value = entry['ObsValue']['Value'];
|
|
||||||
// print('Processing value: $value, type: ${value.runtimeType}'); // Debug each value
|
|
||||||
//
|
|
||||||
// return value.toString(); // Convert to string
|
|
||||||
// }).fold(0.0, (prev, element) => prev + element);
|
|
||||||
|
|
||||||
ValueNotifier<int?> touchedIndex = ValueNotifier(null);
|
ValueNotifier<int?> touchedIndex = ValueNotifier(null);
|
||||||
|
|
||||||
@ -324,6 +278,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
SizedBox(height: 15),
|
SizedBox(height: 15),
|
||||||
|
|
||||||
Text(
|
Text(
|
||||||
chartData['chart_sub_heading'] ?? '',
|
chartData['chart_sub_heading'] ?? '',
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
@ -333,6 +288,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
textAlign: TextAlign.center,
|
textAlign: TextAlign.center,
|
||||||
),
|
),
|
||||||
SizedBox(height: 70),
|
SizedBox(height: 70),
|
||||||
|
|
||||||
Expanded(
|
Expanded(
|
||||||
child: ValueListenableBuilder<int?>(
|
child: ValueListenableBuilder<int?>(
|
||||||
valueListenable: touchedIndex,
|
valueListenable: touchedIndex,
|
||||||
@ -355,13 +311,16 @@ class ChartWidget extends StatelessWidget {
|
|||||||
null; // Reset when not touching
|
null; // Reset when not touching
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
SizedBox(height: 65),
|
SizedBox(height:105),
|
||||||
Flexible(
|
Flexible(
|
||||||
// child: SingleChildScrollView(
|
// child: SingleChildScrollView(
|
||||||
// scrollDirection: Axis.horizontal,
|
// scrollDirection: Axis.horizontal,
|
||||||
@ -434,11 +393,11 @@ class ChartWidget extends StatelessWidget {
|
|||||||
fitInsideHorizontally: true,
|
fitInsideHorizontally: true,
|
||||||
fitInsideVertically: true,
|
fitInsideVertically: true,
|
||||||
// tooltipPadding: const EdgeInsets.all(8),
|
// tooltipPadding: const EdgeInsets.all(8),
|
||||||
tooltipPadding: const EdgeInsets.symmetric(
|
tooltipPadding: const EdgeInsets.symmetric(horizontal: 4, vertical: 8), // Optional
|
||||||
horizontal: 4, vertical: 8), // Optional
|
|
||||||
tooltipHorizontalAlignment: FLHorizontalAlignment.left,
|
tooltipHorizontalAlignment: FLHorizontalAlignment.left,
|
||||||
tooltipMargin: 16,
|
tooltipMargin: 16,
|
||||||
|
|
||||||
|
|
||||||
getTooltipItem:
|
getTooltipItem:
|
||||||
(groupData, groupIndex, rodData, rodIndex) {
|
(groupData, groupIndex, rodData, rodIndex) {
|
||||||
// Get the list of group names dynamically
|
// Get the list of group names dynamically
|
||||||
@ -633,9 +592,10 @@ class ChartWidget extends StatelessWidget {
|
|||||||
// (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']))
|
// (entry) => double.parse(entry['ObsKey']['TIME_PERIOD']))
|
||||||
// .toSet();
|
// .toSet();
|
||||||
|
|
||||||
Set<String> uniqueXValues = filteredData.map<String>((entry) {
|
|
||||||
String? timePeriod =
|
Set<String> uniqueXValues = filteredData
|
||||||
entry['ObsKey']['TIME_PERIOD']; // Nullable String
|
.map<String>((entry) {
|
||||||
|
String? timePeriod = entry['ObsKey']['TIME_PERIOD']; // Nullable String
|
||||||
print('TIME_PERIOD- $timePeriod');
|
print('TIME_PERIOD- $timePeriod');
|
||||||
|
|
||||||
if (timePeriod == null) {
|
if (timePeriod == null) {
|
||||||
@ -657,7 +617,8 @@ class ChartWidget extends StatelessWidget {
|
|||||||
print('Unknown format: $timePeriod');
|
print('Unknown format: $timePeriod');
|
||||||
return timePeriod; // Keep it as is
|
return timePeriod; // Keep it as is
|
||||||
}
|
}
|
||||||
}).toSet();
|
})
|
||||||
|
.toSet();
|
||||||
|
|
||||||
print("Unique X Values: $uniqueXValues");
|
print("Unique X Values: $uniqueXValues");
|
||||||
|
|
||||||
@ -666,30 +627,18 @@ class ChartWidget extends StatelessWidget {
|
|||||||
if (RegExp(r'^\d{4}$').hasMatch(timePeriod)) {
|
if (RegExp(r'^\d{4}$').hasMatch(timePeriod)) {
|
||||||
return double.parse(timePeriod); // Year-only (2019 → 2019.0)
|
return double.parse(timePeriod); // Year-only (2019 → 2019.0)
|
||||||
} else if (RegExp(r'^\d{4}-\d{2}$').hasMatch(timePeriod)) {
|
} else if (RegExp(r'^\d{4}-\d{2}$').hasMatch(timePeriod)) {
|
||||||
return double.parse(timePeriod.replaceAll(
|
return double.parse(timePeriod.replaceAll('-', '.')); // Year-Month (2019-11 → 2019.11)
|
||||||
'-', '.')); // Year-Month (2019-11 → 2019.11)
|
|
||||||
} else if (RegExp(r'^\d{4}-[A-Za-z]{3}$').hasMatch(timePeriod)) {
|
} else if (RegExp(r'^\d{4}-[A-Za-z]{3}$').hasMatch(timePeriod)) {
|
||||||
// Year-MonthAbbr (2019-Nov)
|
// Year-MonthAbbr (2019-Nov)
|
||||||
Map<String, int> monthMap = {
|
Map<String, int> monthMap = {
|
||||||
'Jan': 1,
|
'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4,
|
||||||
'Feb': 2,
|
'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8,
|
||||||
'Mar': 3,
|
'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12
|
||||||
'Apr': 4,
|
|
||||||
'May': 5,
|
|
||||||
'Jun': 6,
|
|
||||||
'Jul': 7,
|
|
||||||
'Aug': 8,
|
|
||||||
'Sep': 9,
|
|
||||||
'Oct': 10,
|
|
||||||
'Nov': 11,
|
|
||||||
'Dec': 12
|
|
||||||
};
|
};
|
||||||
|
|
||||||
List<String> parts = timePeriod.split('-');
|
List<String> parts = timePeriod.split('-');
|
||||||
int month =
|
int month = monthMap[parts[1]] ?? 1; // Default to January if unknown
|
||||||
monthMap[parts[1]] ?? 1; // Default to January if unknown
|
return double.parse('${parts[0]}.$month'); // Convert to format (2019-Nov → 2019.11)
|
||||||
return double.parse(
|
|
||||||
'${parts[0]}.$month'); // Convert to format (2019-Nov → 2019.11)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
throw FormatException("Invalid TIME_PERIOD format: $timePeriod");
|
throw FormatException("Invalid TIME_PERIOD format: $timePeriod");
|
||||||
@ -701,12 +650,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
.toSet();
|
.toSet();
|
||||||
print('Processed X Values: $uniqueXValuesProcessed');
|
print('Processed X Values: $uniqueXValuesProcessed');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print('LnTrnd2.1');
|
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');
|
print('LnTrnd3');
|
||||||
|
|
||||||
return Column(children: [
|
return Column(children: [
|
||||||
@ -730,6 +682,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
SizedBox(height: 10),
|
SizedBox(height: 10),
|
||||||
// Chart
|
// Chart
|
||||||
Expanded(
|
Expanded(
|
||||||
|
|
||||||
child: LineChart(LineChartData(
|
child: LineChart(LineChartData(
|
||||||
lineTouchData: lineTouchData1(),
|
lineTouchData: lineTouchData1(),
|
||||||
gridData: gridData(),
|
gridData: gridData(),
|
||||||
@ -739,10 +692,12 @@ class ChartWidget extends StatelessWidget {
|
|||||||
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),
|
// minX: uniqueXValuesProcessed.reduce((a, b) => a < b ? a : b),
|
||||||
// maxX: 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),
|
||||||
child: Wrap(
|
child: Wrap(
|
||||||
@ -991,6 +946,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
// Extract groupBy values and their corresponding y-axis values
|
// Extract groupBy values and their corresponding y-axis values
|
||||||
List<String> xAxisData = [];
|
List<String> xAxisData = [];
|
||||||
List<double> yAxisData = [];
|
List<double> yAxisData = [];
|
||||||
|
List<String> yAxisLabels = [];
|
||||||
|
|
||||||
var xadditionalgrp= chartData['chart_type_json']['additional_x_group'];
|
var xadditionalgrp= chartData['chart_type_json']['additional_x_group'];
|
||||||
|
|
||||||
@ -999,9 +955,9 @@ class ChartWidget extends StatelessWidget {
|
|||||||
for (var entry in chartData['response']) {
|
for (var entry in chartData['response']) {
|
||||||
var xValue = entry['ObsKey'][groupByKey];
|
var xValue = entry['ObsKey'][groupByKey];
|
||||||
var xTimePeriod= entry['ObsKey']['TIME_PERIOD'];
|
var xTimePeriod= entry['ObsKey']['TIME_PERIOD'];
|
||||||
|
var unitMsr = entry['ObsKey']['UNIT_MEASURE'];
|
||||||
var yValue = entry['ObsValue']['Value'];
|
var yValue = entry['ObsValue']['Value'];
|
||||||
var xadditionalgroup =
|
var xadditionalgroup= chartData['chart_type_json']['additional_x_group'];
|
||||||
chartData['chart_type_json']['additional_x_group'];
|
|
||||||
|
|
||||||
print('chartData response: ${chartData['response']}');
|
print('chartData response: ${chartData['response']}');
|
||||||
|
|
||||||
@ -1009,22 +965,18 @@ class ChartWidget extends StatelessWidget {
|
|||||||
print('Xadditionalt-$xTimePeriod');
|
print('Xadditionalt-$xTimePeriod');
|
||||||
print('xadditionalgroup-$xadditionalgroup');
|
print('xadditionalgroup-$xadditionalgroup');
|
||||||
print('yValue-$yValue');
|
print('yValue-$yValue');
|
||||||
|
print('unitMsr-$unitMsr');
|
||||||
|
|
||||||
|
|
||||||
if (xadditionalgrp == 'TIME_PERIOD') {
|
if (xadditionalgrp == 'TIME_PERIOD') {
|
||||||
chartData['response'].sort((a, b) {
|
chartData['response'].sort((a, b) {
|
||||||
// Convert TIME_PERIOD to int for proper sorting
|
// Convert TIME_PERIOD to int for proper sorting
|
||||||
int timeA =
|
int timeA = int.tryParse(a['ObsKey']['TIME_PERIOD'].toString()) ?? 0;
|
||||||
int.tryParse(a['ObsKey']['TIME_PERIOD'].toString()) ?? 0;
|
int timeB = int.tryParse(b['ObsKey']['TIME_PERIOD'].toString()) ?? 0;
|
||||||
int timeB =
|
|
||||||
int.tryParse(b['ObsKey']['TIME_PERIOD'].toString()) ?? 0;
|
|
||||||
|
|
||||||
// Extract QUARTER and convert "Q1", "Q2", etc. to numeric values
|
// 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;
|
||||||
a['ObsKey']['QUARTER'].toString().replaceAll('Q', '')) ??
|
int quarterB = int.tryParse(b['ObsKey']['QUARTER'].toString().replaceAll('Q', '')) ?? 0;
|
||||||
0;
|
|
||||||
int quarterB = int.tryParse(
|
|
||||||
b['ObsKey']['QUARTER'].toString().replaceAll('Q', '')) ??
|
|
||||||
0;
|
|
||||||
|
|
||||||
// First, sort by TIME_PERIOD. If equal, sort by QUARTER
|
// First, sort by TIME_PERIOD. If equal, sort by QUARTER
|
||||||
if (timeA != timeB) {
|
if (timeA != timeB) {
|
||||||
@ -1047,8 +999,12 @@ class ChartWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
xAxisData.add(xLabel);
|
xAxisData.add(xLabel);
|
||||||
|
|
||||||
yAxisData.add(double.tryParse(yValue.toString()) ?? 0.0);
|
yAxisData.add(double.tryParse(yValue.toString()) ?? 0.0);
|
||||||
|
yAxisLabels.add(unitMsr ?? '');
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
return Column(children: [
|
return Column(children: [
|
||||||
Text(
|
Text(
|
||||||
@ -1077,6 +1033,8 @@ class ChartWidget extends StatelessWidget {
|
|||||||
maxY: yAxisData.isNotEmpty
|
maxY: yAxisData.isNotEmpty
|
||||||
? yAxisData.reduce((a, b) => a > b ? a : b) * 1.2
|
? yAxisData.reduce((a, b) => a > b ? a : b) * 1.2
|
||||||
: 10,
|
: 10,
|
||||||
|
|
||||||
|
|
||||||
// barTouchData: BarTouchData(enabled: true),
|
// barTouchData: BarTouchData(enabled: true),
|
||||||
barTouchData: BarTouchData(
|
barTouchData: BarTouchData(
|
||||||
enabled: true,
|
enabled: true,
|
||||||
@ -1087,8 +1045,13 @@ class ChartWidget extends StatelessWidget {
|
|||||||
// tooltipPadding: const EdgeInsets.all(8),
|
// tooltipPadding: const EdgeInsets.all(8),
|
||||||
// tooltipMargin: 16,
|
// tooltipMargin: 16,
|
||||||
getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
||||||
|
|
||||||
|
String unitMsrLabel = yAxisLabels.isNotEmpty && groupIndex < yAxisLabels.length
|
||||||
|
? yAxisLabels[groupIndex]
|
||||||
|
: '';
|
||||||
|
|
||||||
return BarTooltipItem(
|
return BarTooltipItem(
|
||||||
rod.toY.toStringAsFixed(1),
|
'${rod.toY.toStringAsFixed(1)}\n$unitMsrLabel',
|
||||||
const TextStyle(color: Colors.white),
|
const TextStyle(color: Colors.white),
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
@ -1122,8 +1085,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
: title;
|
: title;
|
||||||
|
|
||||||
return Padding(
|
return Padding(
|
||||||
padding:
|
padding: const EdgeInsets.only(top: 8.0,left: 55.0),
|
||||||
const EdgeInsets.only(top: 8.0, left: 55.0),
|
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 60, // Limit width to force wrapping
|
width: 60, // Limit width to force wrapping
|
||||||
child: Transform.rotate(
|
child: Transform.rotate(
|
||||||
@ -1133,41 +1095,34 @@ class ChartWidget extends StatelessWidget {
|
|||||||
child: TooltipTheme(
|
child: TooltipTheme(
|
||||||
data: TooltipThemeData(
|
data: TooltipThemeData(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.blueGrey[
|
color: Colors.blueGrey[800], // Change background color
|
||||||
800], // Change background color
|
borderRadius: BorderRadius.circular(8), // Optional: rounded corners
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
8), // Optional: rounded corners
|
|
||||||
),
|
),
|
||||||
textStyle: TextStyle(
|
textStyle: TextStyle(color: Colors.white), // Change text color
|
||||||
color: Colors
|
|
||||||
.white), // Change text color
|
|
||||||
),
|
),
|
||||||
|
|
||||||
child: TooltipTheme(
|
child: TooltipTheme(
|
||||||
data: TooltipThemeData(
|
data: TooltipThemeData(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.blueGrey[
|
color: Colors.blueGrey[800], // Change background color
|
||||||
800], // Change background color
|
borderRadius: BorderRadius.circular(8), // Optional: rounded corners
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
8), // Optional: rounded corners
|
|
||||||
),
|
),
|
||||||
textStyle: TextStyle(
|
textStyle: TextStyle(color: Colors.white), // Change text color
|
||||||
color: Colors
|
|
||||||
.white), // Change text color
|
|
||||||
),
|
),
|
||||||
child: Tooltip(
|
child: Tooltip(
|
||||||
message: title,
|
message: title,
|
||||||
|
|
||||||
child: Text(
|
child: Text(
|
||||||
// title,
|
// title,
|
||||||
displayTitle,
|
displayTitle,
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
style: TextStyle(
|
style: TextStyle(fontSize: 10,),
|
||||||
fontSize: 10,
|
|
||||||
),
|
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
|
),),
|
||||||
),
|
),
|
||||||
|
|
||||||
),
|
),
|
||||||
),
|
|
||||||
),
|
|
||||||
)));
|
)));
|
||||||
}
|
}
|
||||||
return Container();
|
return Container();
|
||||||
@ -1308,8 +1263,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
topTitles: AxisTitles(
|
topTitles: AxisTitles(
|
||||||
sideTitles:
|
sideTitles: SideTitles(showTitles: false), // Hide top titles
|
||||||
SideTitles(showTitles: false), // Hide top titles
|
|
||||||
),
|
),
|
||||||
rightTitles: AxisTitles(
|
rightTitles: AxisTitles(
|
||||||
sideTitles:
|
sideTitles:
|
||||||
@ -1333,8 +1287,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
),
|
),),
|
||||||
),
|
|
||||||
]);
|
]);
|
||||||
case 'fl_multi_bar':
|
case 'fl_multi_bar':
|
||||||
double _calculateChartWidth(dynamic chartData) {
|
double _calculateChartWidth(dynamic chartData) {
|
||||||
@ -1346,10 +1299,14 @@ class ChartWidget extends StatelessWidget {
|
|||||||
// 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']) {
|
for (var item in chartData['response']) {
|
||||||
|
|
||||||
print("MultiBArRaw item: $item");
|
print("MultiBArRaw item: $item");
|
||||||
|
|
||||||
String crop = item['ObsKey'][cropKey];
|
String crop = item['ObsKey'][cropKey];
|
||||||
@ -1357,8 +1314,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
|
|
||||||
// Use a Set to avoid duplicates
|
// Use a Set to avoid duplicates
|
||||||
if (groupedCrops.containsKey(cropType)) {
|
if (groupedCrops.containsKey(cropType)) {
|
||||||
groupedCrops[cropType] =
|
groupedCrops[cropType] = (groupedCrops[cropType]! + [crop]).toSet().toList();
|
||||||
(groupedCrops[cropType]! + [crop]).toSet().toList();
|
|
||||||
} else {
|
} else {
|
||||||
groupedCrops[cropType] = [crop];
|
groupedCrops[cropType] = [crop];
|
||||||
}
|
}
|
||||||
@ -1380,6 +1336,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
//
|
//
|
||||||
// print('groupedCropsflmutli- $groupedCrops');
|
// print('groupedCropsflmutli- $groupedCrops');
|
||||||
|
|
||||||
|
|
||||||
return Center(
|
return Center(
|
||||||
child: Column(children: [
|
child: Column(children: [
|
||||||
Text(
|
Text(
|
||||||
@ -1410,8 +1367,8 @@ class ChartWidget extends StatelessWidget {
|
|||||||
child: BarChart(
|
child: BarChart(
|
||||||
BarChartData(
|
BarChartData(
|
||||||
alignment: BarChartAlignment.spaceAround,
|
alignment: BarChartAlignment.spaceAround,
|
||||||
maxY: _calculateMaxY(
|
maxY:
|
||||||
chartData), // Dynamically calculate max Y
|
_calculateMaxY(chartData), // Dynamically calculate max Y
|
||||||
barGroups: _buildHorizontalRotateBarGroups(
|
barGroups: _buildHorizontalRotateBarGroups(
|
||||||
chartData, groupByValues), // Build bar groups
|
chartData, groupByValues), // Build bar groups
|
||||||
titlesData: FlTitlesData(
|
titlesData: FlTitlesData(
|
||||||
@ -1434,21 +1391,16 @@ class ChartWidget extends StatelessWidget {
|
|||||||
return Padding(
|
return Padding(
|
||||||
padding: const EdgeInsets.only(top: 8.0),
|
padding: const EdgeInsets.only(top: 8.0),
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width:
|
width: 60, // Limit width to force wrapping
|
||||||
60, // Limit width to force wrapping
|
|
||||||
child: Transform.rotate(
|
child: Transform.rotate(
|
||||||
angle: -0.5,
|
angle: -0.5,
|
||||||
child: TooltipTheme(
|
child: TooltipTheme(
|
||||||
data: TooltipThemeData(
|
data: TooltipThemeData(
|
||||||
decoration: BoxDecoration(
|
decoration: BoxDecoration(
|
||||||
color: Colors.blueGrey[
|
color: Colors.blueGrey[800], // Change background color
|
||||||
800], // Change background color
|
borderRadius: BorderRadius.circular(8), // Optional: rounded corners
|
||||||
borderRadius: BorderRadius.circular(
|
|
||||||
8), // Optional: rounded corners
|
|
||||||
),
|
),
|
||||||
textStyle: TextStyle(
|
textStyle: TextStyle(color: Colors.white), // Change text color
|
||||||
color: Colors
|
|
||||||
.white), // Change text color
|
|
||||||
),
|
),
|
||||||
child: Tooltip(
|
child: Tooltip(
|
||||||
message: title,
|
message: title,
|
||||||
@ -1458,6 +1410,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
// style: TextStyle(backgroundColor: Colors.blueGrey[800]),
|
// style: TextStyle(backgroundColor: Colors.blueGrey[800]),
|
||||||
overflow: TextOverflow.ellipsis,
|
overflow: TextOverflow.ellipsis,
|
||||||
)),
|
)),
|
||||||
|
|
||||||
),
|
),
|
||||||
)));
|
)));
|
||||||
// return Transform.rotate(
|
// return Transform.rotate(
|
||||||
@ -1481,8 +1434,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
borderData: FlBorderData(show: false),
|
borderData: FlBorderData(show: false),
|
||||||
barTouchData: BarTouchData(
|
barTouchData: BarTouchData(
|
||||||
touchTooltipData: BarTouchTooltipData(
|
touchTooltipData: BarTouchTooltipData(
|
||||||
tooltipHorizontalAlignment:
|
tooltipHorizontalAlignment: FLHorizontalAlignment.center,
|
||||||
FLHorizontalAlignment.center,
|
|
||||||
tooltipRoundedRadius: 8,
|
tooltipRoundedRadius: 8,
|
||||||
fitInsideHorizontally:
|
fitInsideHorizontally:
|
||||||
true, // Ensure it fits within the screen
|
true, // Ensure it fits within the screen
|
||||||
@ -1500,8 +1452,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
groupByValues.elementAt(groupIndex);
|
groupByValues.elementAt(groupIndex);
|
||||||
|
|
||||||
// Fetch the crop for the current group from groupedCrops
|
// Fetch the crop for the current group from groupedCrops
|
||||||
String cropType =
|
String cropType = groupByValues.elementAt(groupIndex);
|
||||||
groupByValues.elementAt(groupIndex);
|
|
||||||
print('GrpcropType: $cropType');
|
print('GrpcropType: $cropType');
|
||||||
// String crop = groupedCrops[cropType]![rodIndex];
|
// String crop = groupedCrops[cropType]![rodIndex];
|
||||||
|
|
||||||
@ -1514,9 +1465,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
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)
|
crop = (crops != null && crops.isNotEmpty) ? crops.first : cropType;
|
||||||
? crops.first
|
|
||||||
: cropType;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// print('groupedCrops1: $groupedCrops - $rodIndex');
|
// print('groupedCrops1: $groupedCrops - $rodIndex');
|
||||||
@ -1563,8 +1512,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
response != null &&
|
response != null &&
|
||||||
response.spot != null) {
|
response.spot != null) {
|
||||||
// setState(() {
|
// setState(() {
|
||||||
touchedGroupIndex =
|
touchedGroupIndex = response.spot!.touchedBarGroupIndex;
|
||||||
response.spot!.touchedBarGroupIndex;
|
|
||||||
// });
|
// });
|
||||||
} else {
|
} else {
|
||||||
// setState(() {
|
// setState(() {
|
||||||
@ -1607,10 +1555,10 @@ class ChartWidget extends StatelessWidget {
|
|||||||
|
|
||||||
int numberOfBars =
|
int numberOfBars =
|
||||||
groupedCrops.length; // Number of grouped sets (bar groups)
|
groupedCrops.length; // Number of grouped sets (bar groups)
|
||||||
double barHeight = 40.0; // Height per individual bar
|
double barHeight = 10.0; // Height per individual bar
|
||||||
double barSpacing = 30.0; // Space between bar sets
|
double barSpacing = 1.0; // Space between bar sets
|
||||||
double minHeight = 300.0; // Minimum chart height
|
double minHeight = 300.0; // Minimum chart height
|
||||||
double maxHeight = 1000.0; // Maximum chart height
|
double maxHeight = 500.0; // Maximum chart height
|
||||||
|
|
||||||
// Calculate total height dynamically
|
// Calculate total height dynamically
|
||||||
double chartHeight =
|
double chartHeight =
|
||||||
@ -1629,6 +1577,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
SizedBox(height: 5),
|
SizedBox(height: 5),
|
||||||
Text(
|
Text(
|
||||||
chartData['chart_sub_heading'] ?? '',
|
chartData['chart_sub_heading'] ?? '',
|
||||||
|
|
||||||
style: TextStyle(
|
style: TextStyle(
|
||||||
fontSize: 13,
|
fontSize: 13,
|
||||||
fontWeight: FontWeight.w300,
|
fontWeight: FontWeight.w300,
|
||||||
@ -1640,22 +1589,24 @@ class ChartWidget extends StatelessWidget {
|
|||||||
Expanded(
|
Expanded(
|
||||||
child: SingleChildScrollView(
|
child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.vertical,
|
scrollDirection: Axis.vertical,
|
||||||
child: SingleChildScrollView(
|
// child: SingleChildScrollView(
|
||||||
scrollDirection: Axis.horizontal,
|
// scrollDirection: Axis.horizontal,
|
||||||
|
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 1000,
|
// width: 500,
|
||||||
|
// width: 1000,
|
||||||
height: chartHeight,
|
height: chartHeight,
|
||||||
child: BarChart(
|
child: Stack(
|
||||||
|
children: [
|
||||||
|
BarChart(
|
||||||
BarChartData(
|
BarChartData(
|
||||||
maxY: 400000,
|
maxY: 400000,
|
||||||
rotationQuarterTurns: rotationTurns,
|
rotationQuarterTurns: rotationTurns,
|
||||||
barTouchData: BarTouchData(
|
barTouchData: BarTouchData(
|
||||||
touchTooltipData: BarTouchTooltipData(
|
touchTooltipData: BarTouchTooltipData(
|
||||||
tooltipHorizontalAlignment:
|
tooltipHorizontalAlignment: FLHorizontalAlignment.center,
|
||||||
FLHorizontalAlignment.center,
|
|
||||||
tooltipRoundedRadius: 8,
|
tooltipRoundedRadius: 8,
|
||||||
fitInsideHorizontally:
|
fitInsideHorizontally: true, // Ensure it fits within the screen
|
||||||
true, // Ensure it fits within the screen
|
|
||||||
fitInsideVertically: true,
|
fitInsideVertically: true,
|
||||||
tooltipPadding: EdgeInsets.all(8),
|
tooltipPadding: EdgeInsets.all(8),
|
||||||
tooltipMargin: 16,
|
tooltipMargin: 16,
|
||||||
@ -1728,21 +1679,24 @@ class ChartWidget extends StatelessWidget {
|
|||||||
titlesData: FlTitlesData(
|
titlesData: FlTitlesData(
|
||||||
leftTitles: AxisTitles(
|
leftTitles: AxisTitles(
|
||||||
sideTitles: SideTitles(
|
sideTitles: SideTitles(
|
||||||
showTitles: false,
|
// showTitles: false,
|
||||||
reservedSize: 20,
|
reservedSize: 40,
|
||||||
interval: 100000,
|
interval: 100000,
|
||||||
getTitlesWidget: (value, meta) {
|
getTitlesWidget: (value, meta) {
|
||||||
return Text(
|
return SizedBox(
|
||||||
|
width: 50,
|
||||||
|
child: Text(
|
||||||
value.toInt().toString(),
|
value.toInt().toString(),
|
||||||
style: const TextStyle(fontSize: 12),
|
textAlign: TextAlign.justify,
|
||||||
);
|
style: const TextStyle(fontSize: 12,),
|
||||||
|
),);
|
||||||
},
|
},
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
bottomTitles: AxisTitles(
|
bottomTitles: AxisTitles(
|
||||||
sideTitles: SideTitles(
|
sideTitles: SideTitles(
|
||||||
showTitles: true,
|
showTitles: true,
|
||||||
reservedSize: 80, // Added space for rotated titles
|
reservedSize: 150, // Added space for rotated titles
|
||||||
getTitlesWidget: (value, meta) {
|
getTitlesWidget: (value, meta) {
|
||||||
if (value < groupByValues.length) {
|
if (value < groupByValues.length) {
|
||||||
String title =
|
String title =
|
||||||
@ -1752,9 +1706,10 @@ class ChartWidget extends StatelessWidget {
|
|||||||
-1.58, // Rotation in radians (~ -30 degrees)
|
-1.58, // Rotation in radians (~ -30 degrees)
|
||||||
child: Center(
|
child: Center(
|
||||||
child: SizedBox(
|
child: SizedBox(
|
||||||
width: 80,
|
width: 120,
|
||||||
child: Text(
|
child: Text(
|
||||||
title,
|
title,
|
||||||
|
textAlign: TextAlign.end,
|
||||||
style: const TextStyle(fontSize: 12),
|
style: const TextStyle(fontSize: 12),
|
||||||
softWrap: true,
|
softWrap: true,
|
||||||
maxLines: 2,
|
maxLines: 2,
|
||||||
@ -1802,191 +1757,13 @@ class ChartWidget extends StatelessWidget {
|
|||||||
alignment: BarChartAlignment.spaceAround,
|
alignment: BarChartAlignment.spaceAround,
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
|
||||||
|
])
|
||||||
),
|
),
|
||||||
),
|
|
||||||
|
// ),
|
||||||
)),
|
)),
|
||||||
// Expanded(
|
|
||||||
// child: Stack(
|
|
||||||
// children:[
|
|
||||||
// BarChart(
|
|
||||||
// BarChartData(
|
|
||||||
// maxY: 400000,
|
|
||||||
// rotationQuarterTurns: rotationTurns,
|
|
||||||
// barTouchData: BarTouchData(
|
|
||||||
// touchTooltipData: BarTouchTooltipData(
|
|
||||||
// tooltipHorizontalAlignment: FLHorizontalAlignment.center,
|
|
||||||
// // Only show tooltip when touched
|
|
||||||
// getTooltipItem: (group, groupIndex, rod, rodIndex) {
|
|
||||||
// if (rod.toY == 0 || touchedGroupIndex == -1) {
|
|
||||||
// return null; // Don't show the tooltip if the value is 0 or there's no touch
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// if (groupIndex == touchedGroupIndex) {
|
|
||||||
// // print('Group Index: $groupIndex, Group : $group');
|
|
||||||
//
|
|
||||||
// // Get the group label dynamically
|
|
||||||
// String groupLabel = groupByValues.elementAt(groupIndex);
|
|
||||||
//
|
|
||||||
// // Fetch the crop for the current group from groupedCrops
|
|
||||||
// String cropType = groupByValues.elementAt(groupIndex);
|
|
||||||
// String crop = groupedCrops[cropType]![rodIndex];
|
|
||||||
// double value = rod.toY;
|
|
||||||
//
|
|
||||||
// String formattedValue;
|
|
||||||
// if (value >= 1000000) {
|
|
||||||
// formattedValue =
|
|
||||||
// (value / 1000000).toStringAsFixed(1) + 'M';
|
|
||||||
// } else if (value >= 1000) {
|
|
||||||
// formattedValue =
|
|
||||||
// (value / 1000).toStringAsFixed(1) + 'K';
|
|
||||||
// } else {
|
|
||||||
// formattedValue = value
|
|
||||||
// .toStringAsFixed(0); // for values smaller than 1000
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// return BarTooltipItem(
|
|
||||||
// '$groupLabel\n$crop',
|
|
||||||
// const TextStyle(
|
|
||||||
// color: Colors.white,
|
|
||||||
// fontWeight: FontWeight.bold,
|
|
||||||
// ),
|
|
||||||
// children: [
|
|
||||||
// TextSpan(
|
|
||||||
// text: ' Value: $formattedValue',
|
|
||||||
// style: const TextStyle(
|
|
||||||
// color: Colors.yellow,
|
|
||||||
// fontWeight: FontWeight.w500,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ],
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// return null;
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// touchCallback: (event, response) {
|
|
||||||
// if (event.isInterestedForInteractions &&
|
|
||||||
// response != null &&
|
|
||||||
// response.spot != null) {
|
|
||||||
// // setState(() {
|
|
||||||
// touchedGroupIndex = response.spot!.touchedBarGroupIndex;
|
|
||||||
// // });
|
|
||||||
// } else {
|
|
||||||
// // setState(() {
|
|
||||||
// touchedGroupIndex = -1; // Reset if no interaction
|
|
||||||
// // });
|
|
||||||
// }
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// titlesData: FlTitlesData(
|
|
||||||
// leftTitles: AxisTitles(
|
|
||||||
// sideTitles: SideTitles(
|
|
||||||
// showTitles: false,
|
|
||||||
// reservedSize: 20,
|
|
||||||
// interval: 100000,
|
|
||||||
// getTitlesWidget: (value, meta) {
|
|
||||||
// return Text(
|
|
||||||
// value.toInt().toString(),
|
|
||||||
// style: const TextStyle(fontSize: 12),
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// bottomTitles: AxisTitles(
|
|
||||||
// sideTitles: SideTitles(
|
|
||||||
// showTitles: true,
|
|
||||||
// reservedSize: 80, // Added space for rotated titles
|
|
||||||
// getTitlesWidget: (value, meta) {
|
|
||||||
// if (value < groupByValues.length) {
|
|
||||||
// String title = groupByValues.elementAt(value.toInt());
|
|
||||||
// return Transform.rotate(
|
|
||||||
// angle: -1.58, // Rotation in radians (~ -30 degrees)
|
|
||||||
// child: Center(
|
|
||||||
// child: SizedBox(
|
|
||||||
// width: 80,
|
|
||||||
// child: Text(
|
|
||||||
// title,
|
|
||||||
// style: const TextStyle(fontSize: 12),
|
|
||||||
// softWrap: true,
|
|
||||||
// maxLines: 2,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }
|
|
||||||
// return const SizedBox.shrink();
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// rightTitles:
|
|
||||||
// AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
|
||||||
// topTitles:
|
|
||||||
// AxisTitles(sideTitles: SideTitles(showTitles: false)),
|
|
||||||
// ),
|
|
||||||
// borderData: FlBorderData(
|
|
||||||
// show: true,
|
|
||||||
// border: const Border(
|
|
||||||
// // left: BorderSide(color: Colors.grey),
|
|
||||||
// bottom: BorderSide(color: Colors.white),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// gridData: FlGridData(
|
|
||||||
// show: false,
|
|
||||||
// drawVerticalLine: true,
|
|
||||||
// verticalInterval: 1,
|
|
||||||
// horizontalInterval: 100000,
|
|
||||||
// getDrawingHorizontalLine: (value) {
|
|
||||||
// return FlLine(
|
|
||||||
// color: Colors.grey.withOpacity(0.5),
|
|
||||||
// strokeWidth: 1,
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// getDrawingVerticalLine: (value) {
|
|
||||||
// return FlLine(
|
|
||||||
// color: Colors.grey.withOpacity(0.5),
|
|
||||||
// strokeWidth: 1,
|
|
||||||
// );
|
|
||||||
// },
|
|
||||||
// ),
|
|
||||||
// barGroups:
|
|
||||||
// _buildHorizontalRotateBarGroups(chartData, groupByValues),
|
|
||||||
// alignment: BarChartAlignment.spaceAround,
|
|
||||||
// ),
|
|
||||||
//
|
|
||||||
// ),
|
|
||||||
// // Overlay Texts
|
|
||||||
// ..._buildHorizontalRotateBarGroups(chartData, groupByValues)
|
|
||||||
// .asMap()
|
|
||||||
// .entries
|
|
||||||
// .expand((entry) {
|
|
||||||
// int groupIndex = entry.key;
|
|
||||||
// BarChartGroupData groupData = entry.value;
|
|
||||||
// return groupData.barRods.asMap().entries.map((rodEntry) {
|
|
||||||
// int rodIndex = rodEntry.key;
|
|
||||||
// BarChartRodData rodData = rodEntry.value;
|
|
||||||
//
|
|
||||||
// // Position calculation
|
|
||||||
// double barHeight = rodData.toY / 400000 * MediaQuery.of(context).size.height;
|
|
||||||
//
|
|
||||||
// return Positioned(
|
|
||||||
// left: (groupIndex * 80).toDouble() + 20, // Adjust based on spacing
|
|
||||||
// bottom: barHeight / 2, // Centered inside the bar
|
|
||||||
// child: Transform.rotate(
|
|
||||||
// angle: -0.1,
|
|
||||||
// child: Text(
|
|
||||||
// // '${rodData.toY.toInt()}',
|
|
||||||
// "123",
|
|
||||||
// style: TextStyle(
|
|
||||||
// color: Colors.black,
|
|
||||||
// fontWeight: FontWeight.bold,
|
|
||||||
// fontSize: 12,
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// ),
|
|
||||||
// );
|
|
||||||
// }).toList();
|
|
||||||
// }).toList(),
|
|
||||||
// ]))
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -2083,6 +1860,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
return lineBars;
|
return lineBars;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Function to parse TIME_PERIOD into a EXACT value
|
/// Function to parse TIME_PERIOD into a EXACT value
|
||||||
double parseTimePeriod(String timePeriod) {
|
double parseTimePeriod(String timePeriod) {
|
||||||
// Match formats
|
// Match formats
|
||||||
@ -2091,23 +1869,13 @@ class ChartWidget extends StatelessWidget {
|
|||||||
return double.parse(timePeriod); // Year as a double (2020 → 2020.0)
|
return double.parse(timePeriod); // Year as a double (2020 → 2020.0)
|
||||||
} else if (RegExp(r'^\d{4}-\d{2}$').hasMatch(timePeriod)) {
|
} else if (RegExp(r'^\d{4}-\d{2}$').hasMatch(timePeriod)) {
|
||||||
// Format: Year-Month (e.g., "2020-10")
|
// Format: Year-Month (e.g., "2020-10")
|
||||||
return double.parse(
|
return double.parse(timePeriod.replaceAll('-', '.')); // Convert "2020-10" → 2020.10
|
||||||
timePeriod.replaceAll('-', '.')); // Convert "2020-10" → 2020.10
|
|
||||||
} else if (RegExp(r'^\d{4}-[A-Za-z]{3}$').hasMatch(timePeriod)) {
|
} else if (RegExp(r'^\d{4}-[A-Za-z]{3}$').hasMatch(timePeriod)) {
|
||||||
// Format: Year-MonthAbbr (e.g., "2020-Oct")
|
// Format: Year-MonthAbbr (e.g., "2020-Oct")
|
||||||
Map<String, int> monthMap = {
|
Map<String, int> monthMap = {
|
||||||
'Jan': 1,
|
'Jan': 1, 'Feb': 2, 'Mar': 3, 'Apr': 4,
|
||||||
'Feb': 2,
|
'May': 5, 'Jun': 6, 'Jul': 7, 'Aug': 8,
|
||||||
'Mar': 3,
|
'Sep': 9, 'Oct': 10, 'Nov': 11, 'Dec': 12
|
||||||
'Apr': 4,
|
|
||||||
'May': 5,
|
|
||||||
'Jun': 6,
|
|
||||||
'Jul': 7,
|
|
||||||
'Aug': 8,
|
|
||||||
'Sep': 9,
|
|
||||||
'Oct': 10,
|
|
||||||
'Nov': 11,
|
|
||||||
'Dec': 12
|
|
||||||
};
|
};
|
||||||
|
|
||||||
List<String> parts = timePeriod.split('-');
|
List<String> parts = timePeriod.split('-');
|
||||||
@ -2119,6 +1887,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
throw FormatException("Invalid TIME_PERIOD format: $timePeriod");
|
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 = [];
|
||||||
@ -2183,6 +1952,9 @@ class ChartWidget extends StatelessWidget {
|
|||||||
|
|
||||||
print('spots - $spots');
|
print('spots - $spots');
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// 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) {
|
||||||
@ -2198,6 +1970,8 @@ class ChartWidget extends StatelessWidget {
|
|||||||
// return FlSpot(xValue, yValue);
|
// return FlSpot(xValue, yValue);
|
||||||
// }).toList();
|
// }).toList();
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
print('lineGrp2');
|
print('lineGrp2');
|
||||||
// Add a line for this group
|
// Add a line for this group
|
||||||
lineBars.add(
|
lineBars.add(
|
||||||
@ -2207,7 +1981,9 @@ class ChartWidget extends StatelessWidget {
|
|||||||
color: groupColorMap[group],
|
color: groupColorMap[group],
|
||||||
barWidth: 3,
|
barWidth: 3,
|
||||||
isStrokeCapRound: true,
|
isStrokeCapRound: true,
|
||||||
|
dotData: FlDotData(show: true),
|
||||||
belowBarData: BarAreaData(show: false),
|
belowBarData: BarAreaData(show: false),
|
||||||
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -2242,11 +2018,11 @@ class ChartWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
|
|
||||||
FlTitlesData titlesData1(Set<double> xValues) {
|
FlTitlesData titlesData1(Set<double> xValues) {
|
||||||
|
|
||||||
print('tileDATa1xvalue - $xValues');
|
print('tileDATa1xvalue - $xValues');
|
||||||
|
|
||||||
double findClosest(double value, Set<double> values) {
|
double findClosest(double value, Set<double> values) {
|
||||||
return values
|
return values.reduce((a, b) => (value - a).abs() < (value - b).abs() ? a : b);
|
||||||
.reduce((a, b) => (value - a).abs() < (value - b).abs() ? a : b);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return FlTitlesData(
|
return FlTitlesData(
|
||||||
@ -2262,13 +2038,15 @@ class ChartWidget extends StatelessWidget {
|
|||||||
// Check if the value is in the millions or thousands range
|
// Check if the value is in the millions or thousands range
|
||||||
|
|
||||||
if (value >= 1000000000000) {
|
if (value >= 1000000000000) {
|
||||||
formattedValue =
|
formattedValue = '${(value / 1000000000000).toStringAsFixed(0)}T';
|
||||||
'${(value / 1000000000000).toStringAsFixed(0)}T';
|
}
|
||||||
} else if (value >= 1000000000) {
|
else if (value >= 1000000000) {
|
||||||
formattedValue = '${(value / 1000000000).toStringAsFixed(0)}B';
|
formattedValue = '${(value / 1000000000).toStringAsFixed(0)}B';
|
||||||
} else if (value >= 1000000) {
|
}
|
||||||
|
else if (value >= 1000000) {
|
||||||
formattedValue = '${(value / 1000000).toStringAsFixed(0)}M';
|
formattedValue = '${(value / 1000000).toStringAsFixed(0)}M';
|
||||||
} else if (value >= 1000) {
|
}
|
||||||
|
else if (value >= 1000) {
|
||||||
formattedValue = '${(value / 1000).toStringAsFixed(0)}k';
|
formattedValue = '${(value / 1000).toStringAsFixed(0)}k';
|
||||||
} else {
|
} else {
|
||||||
formattedValue = value.toStringAsFixed(
|
formattedValue = value.toStringAsFixed(
|
||||||
@ -2300,11 +2078,14 @@ class ChartWidget extends StatelessWidget {
|
|||||||
interval: null,
|
interval: null,
|
||||||
// interval: 10, // Ensure each year is shown only once
|
// interval: 10, // Ensure each year is shown only once
|
||||||
getTitlesWidget: (value, meta) {
|
getTitlesWidget: (value, meta) {
|
||||||
|
|
||||||
print('BtmTiles :-$value');
|
print('BtmTiles :-$value');
|
||||||
print('BtmTilesmeta :-$meta');
|
print('BtmTilesmeta :-$meta');
|
||||||
// if (xValues.contains(value))
|
// if (xValues.contains(value))
|
||||||
double closestValue = findClosest(value, xValues);
|
double closestValue = findClosest(value, xValues);
|
||||||
if ((closestValue - value).abs() < 0.15) {
|
if ((closestValue - value).abs() < 0.15)
|
||||||
|
{
|
||||||
|
|
||||||
print("Bottomtiles");
|
print("Bottomtiles");
|
||||||
print(value);
|
print(value);
|
||||||
return Padding(
|
return Padding(
|
||||||
@ -2430,8 +2211,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
width: 20,
|
width: 20,
|
||||||
// width: barWidth,
|
// width: barWidth,
|
||||||
borderRadius: BorderRadius.zero,
|
borderRadius: BorderRadius.zero,
|
||||||
color: Colors
|
color: Colors.black// This will act as a container for stacked items
|
||||||
.transparent, // This will act as a container for stacked items
|
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
);
|
);
|
||||||
@ -2596,6 +2376,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
toY: value, // Use the parsed value
|
toY: value, // Use the parsed value
|
||||||
color: barColor, // Dynamic color
|
color: barColor, // Dynamic color
|
||||||
width: 20,
|
width: 20,
|
||||||
|
|
||||||
// backDrawRodData: BackgroundBarChartRodData(
|
// backDrawRodData: BackgroundBarChartRodData(
|
||||||
// show: true,
|
// show: true,
|
||||||
// toY: 400000,
|
// toY: 400000,
|
||||||
@ -2626,6 +2407,7 @@ class ChartWidget extends StatelessWidget {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
double calculateBarWidth(BuildContext context, int totalBars) {
|
double calculateBarWidth(BuildContext context, int totalBars) {
|
||||||
double width = MediaQuery.of(context).size.width; // Chart width
|
double width = MediaQuery.of(context).size.width; // Chart width
|
||||||
double padding = 16.0; // Space between bars
|
double padding = 16.0; // Space between bars
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user