made progress towards aqi distribution chart.

This commit is contained in:
Faris Armoush
2025-06-01 12:20:44 +03:00
parent 10f35d3747
commit 7b31914e1c

View File

@ -9,21 +9,22 @@ class AqiDistributionChart extends StatelessWidget {
const AqiDistributionChart({super.key, required this.chartData}); const AqiDistributionChart({super.key, required this.chartData});
final List<AirQualityDataModel> chartData; final List<AirQualityDataModel> chartData;
static const _rodStackItemsSpacing = 4; static const _rodStackItemsSpacing = 0.4;
static const _barWidth = 20.0;
static final _barBorderRadius = BorderRadius.circular(22);
@override @override
Widget build(BuildContext context) { Widget build(BuildContext context) {
return BarChart( return BarChart(
BarChartData( BarChartData(
alignment: BarChartAlignment.spaceAround, maxY: 100.1,
barTouchData: _barTouchData(context),
titlesData: _titlesData(context),
gridData: EnergyManagementChartsHelper.gridData( gridData: EnergyManagementChartsHelper.gridData(
horizontalInterval: 100, horizontalInterval: 20,
), ),
borderData: EnergyManagementChartsHelper.borderData(), borderData: EnergyManagementChartsHelper.borderData(),
barTouchData: _barTouchData(context),
titlesData: _titlesData(context),
barGroups: _buildBarGroups(), barGroups: _buildBarGroups(),
groupsSpace: 12,
), ),
duration: Duration.zero, duration: Duration.zero,
); );
@ -41,8 +42,8 @@ class AqiDistributionChart extends StatelessWidget {
fromY: currentY, fromY: currentY,
toY: currentY + data.aqi!, toY: currentY + data.aqi!,
color: AirQualityDataModel.metricColors['aqi']!, color: AirQualityDataModel.metricColors['aqi']!,
borderRadius: BorderRadius.circular(10), borderRadius: _barBorderRadius,
width: 20, width: _barWidth,
), ),
); );
currentY += data.aqi! + _rodStackItemsSpacing; currentY += data.aqi! + _rodStackItemsSpacing;
@ -54,8 +55,8 @@ class AqiDistributionChart extends StatelessWidget {
fromY: currentY, fromY: currentY,
toY: currentY + data.pm25!, toY: currentY + data.pm25!,
color: AirQualityDataModel.metricColors['pm25']!, color: AirQualityDataModel.metricColors['pm25']!,
borderRadius: BorderRadius.circular(10), borderRadius: _barBorderRadius,
width: 20, width: _barWidth,
), ),
); );
currentY += data.pm25! + _rodStackItemsSpacing; currentY += data.pm25! + _rodStackItemsSpacing;
@ -67,11 +68,11 @@ class AqiDistributionChart extends StatelessWidget {
fromY: currentY, fromY: currentY,
toY: currentY + data.pm10!, toY: currentY + data.pm10!,
color: AirQualityDataModel.metricColors['pm10']!, color: AirQualityDataModel.metricColors['pm10']!,
borderRadius: BorderRadius.circular(10), borderRadius: _barBorderRadius,
width: 20, width: _barWidth,
), ),
); );
currentY += data.pm10! + 2; currentY += data.pm10! + _rodStackItemsSpacing;
} }
if (data.hcho != null) { if (data.hcho != null) {
@ -80,11 +81,11 @@ class AqiDistributionChart extends StatelessWidget {
fromY: currentY, fromY: currentY,
toY: currentY + data.hcho!, toY: currentY + data.hcho!,
color: AirQualityDataModel.metricColors['hcho']!, color: AirQualityDataModel.metricColors['hcho']!,
borderRadius: BorderRadius.circular(10), borderRadius: _barBorderRadius,
width: 20, width: _barWidth,
), ),
); );
currentY += data.hcho! + 2; currentY += data.hcho! + _rodStackItemsSpacing;
} }
if (data.tvoc != null) { if (data.tvoc != null) {
@ -93,11 +94,11 @@ class AqiDistributionChart extends StatelessWidget {
fromY: currentY, fromY: currentY,
toY: currentY + data.tvoc!, toY: currentY + data.tvoc!,
color: AirQualityDataModel.metricColors['tvoc']!, color: AirQualityDataModel.metricColors['tvoc']!,
borderRadius: BorderRadius.circular(10), borderRadius: _barBorderRadius,
width: 20, width: _barWidth,
), ),
); );
currentY += data.tvoc! + 2; currentY += data.tvoc! + _rodStackItemsSpacing;
} }
if (data.co2 != null) { if (data.co2 != null) {
@ -106,11 +107,11 @@ class AqiDistributionChart extends StatelessWidget {
fromY: currentY, fromY: currentY,
toY: currentY + data.co2!, toY: currentY + data.co2!,
color: AirQualityDataModel.metricColors['co2']!, color: AirQualityDataModel.metricColors['co2']!,
borderRadius: BorderRadius.circular(10), borderRadius: _barBorderRadius,
width: 20, width: _barWidth,
), ),
); );
currentY += data.co2! + 2; currentY += data.co2! + _rodStackItemsSpacing;
} }
return BarChartGroupData( return BarChartGroupData(
x: index, x: index,
@ -143,7 +144,7 @@ class AqiDistributionChart extends StatelessWidget {
final metricName = AirQualityDataModel.metricColors.entries final metricName = AirQualityDataModel.metricColors.entries
.firstWhere((entry) => entry.value == item.color) .firstWhere((entry) => entry.value == item.color)
.key .key
.toUpperCase(); .toLowerCase();
return TextSpan( return TextSpan(
text: '$metricName: ${item.toY - item.fromY}\n', text: '$metricName: ${item.toY - item.fromY}\n',
style: context.textTheme.bodySmall?.copyWith( style: context.textTheme.bodySmall?.copyWith(
@ -159,47 +160,55 @@ class AqiDistributionChart extends StatelessWidget {
} }
FlTitlesData _titlesData(BuildContext context) { FlTitlesData _titlesData(BuildContext context) {
final titlesData = EnergyManagementChartsHelper.titlesData(context); final titlesData = EnergyManagementChartsHelper.titlesData(
context,
leftTitlesInterval: 20,
);
return titlesData.copyWith( final leftTitles = titlesData.leftTitles.copyWith(
bottomTitles: AxisTitles( sideTitles: titlesData.leftTitles.sideTitles.copyWith(
sideTitles: SideTitles( reservedSize: 70,
showTitles: true, interval: 20,
getTitlesWidget: (value, meta) { maxIncluded: false,
if (value.toInt() >= chartData.length) return const SizedBox.shrink(); minIncluded: true,
return Padding( getTitlesWidget: (value, meta) => Padding(
padding: const EdgeInsetsDirectional.only(top: 20.0), padding: const EdgeInsetsDirectional.only(end: 12),
child: Text( child: FittedBox(
chartData[value.toInt()].date.day.toString(), alignment: AlignmentDirectional.centerStart,
style: context.textTheme.bodySmall?.copyWith( fit: BoxFit.scaleDown,
color: ColorsManager.lightGreyColor, child: Text(
fontSize: 12, '${value.toStringAsFixed(0)}%',
), style: context.textTheme.bodySmall?.copyWith(
), fontSize: 12,
); color: ColorsManager.lightGreyColor,
},
reservedSize: 32,
),
),
leftTitles: titlesData.leftTitles.copyWith(
sideTitles: titlesData.leftTitles.sideTitles.copyWith(
reservedSize: 70,
getTitlesWidget: (value, meta) => Padding(
padding: const EdgeInsetsDirectional.only(end: 12),
child: FittedBox(
alignment: AlignmentDirectional.centerStart,
fit: BoxFit.scaleDown,
child: Text(
value.toInt().toString(),
style: context.textTheme.bodySmall?.copyWith(
fontSize: 12,
color: ColorsManager.lightGreyColor,
),
), ),
), ),
), ),
), ),
), ),
); );
final bottomTitles = AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: (value, _) => FittedBox(
alignment: AlignmentDirectional.bottomCenter,
fit: BoxFit.scaleDown,
child: Text(
chartData[value.toInt()].date.day.toString(),
style: context.textTheme.bodySmall?.copyWith(
color: ColorsManager.lightGreyColor,
fontSize: 8,
),
),
),
reservedSize: 36,
),
);
return titlesData.copyWith(
leftTitles: leftTitles,
bottomTitles: bottomTitles,
);
} }
} }