Commit fb8b7110 authored by 张宏's avatar 张宏

111

parent 4a218b88
......@@ -49,7 +49,12 @@ class AbnormalCubit extends Cubit<AbnormalState> {
duration: info.duration,
peak: info.peakRecord,
linkAction: info.linkageAction,
chartTitle: trend.chartTitle,
date: trend.chartDate,
unit: trend.unit,
yaxisMax: trend.yaxisMax.toDouble(),
yaxisMin: trend.yaxisMin.toDouble(),
temperatureTimes: trend.dataPoints.map((p) => p.time).toList(),
temperatureSpots: trend.dataPoints.asMap().entries.map((entry) {
return FlSpot(entry.key.toDouble(), entry.value.value);
}).toList(),
......
......@@ -13,7 +13,12 @@ class AlarmInfo {
final String duration;
final String peak;
final String linkAction;
final String chartTitle;
final String date;
final String unit;
final double yaxisMax;
final double yaxisMin;
final List<String> temperatureTimes;
final List<FlSpot> temperatureSpots;
final String alertDeviceId;
......@@ -30,7 +35,12 @@ class AlarmInfo {
required this.duration,
required this.peak,
required this.linkAction,
required this.chartTitle,
required this.date,
required this.unit,
required this.yaxisMax,
required this.yaxisMin,
required this.temperatureTimes,
required this.temperatureSpots,
required this.alertDeviceId,
});
......
......@@ -8,6 +8,39 @@ class TemperatureCharBlock extends StatelessWidget {
const TemperatureCharBlock({super.key, required this.alarmInfo});
double get _minX => 0;
double get _maxX => alarmInfo.temperatureSpots.length > 1
? (alarmInfo.temperatureSpots.length - 1).toDouble()
: 24;
double get _minY => alarmInfo.yaxisMin;
double get _maxY => alarmInfo.yaxisMax > alarmInfo.yaxisMin
? alarmInfo.yaxisMax
: alarmInfo.yaxisMin + 100;
double get _horizontalInterval {
final interval = (_maxY - _minY) / 5;
return interval > 0 ? interval : 20;
}
double get _bottomInterval => alarmInfo.temperatureSpots.length > 1
? (alarmInfo.temperatureSpots.length - 1) / 4
: 6;
String _formatBottomTitle(double value) {
final index = value.toInt();
if (index < 0 || index >= alarmInfo.temperatureTimes.length) {
return '';
}
final time = alarmInfo.temperatureTimes[index];
if (time.length >= 5) {
return time.substring(0, 5);
}
return time;
}
@override
Widget build(BuildContext context) {
return Container(
......@@ -25,23 +58,25 @@ class TemperatureCharBlock extends StatelessWidget {
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Text(
'24小时温度趋势',
alarmInfo.chartTitle.isEmpty
? '24小时温度趋势'
: alarmInfo.chartTitle,
style: TextStyle(
fontSize: 24.sp,
color: Color.fromRGBO(100, 116, 139, 1),
color: const Color.fromRGBO(100, 116, 139, 1),
),
),
Text(
alarmInfo.date,
style: TextStyle(
fontSize: 24.sp,
color: Color.fromRGBO(100, 116, 139, 1),
color: const Color.fromRGBO(100, 116, 139, 1),
),
),
],
),
SizedBox(height: 20.h),
Container(
SizedBox(
height: 250.h,
child: LineChart(
LineChartData(
......@@ -49,9 +84,9 @@ class TemperatureCharBlock extends StatelessWidget {
show: true,
drawHorizontalLine: true,
drawVerticalLine: false,
horizontalInterval: 10,
horizontalInterval: _horizontalInterval,
getDrawingHorizontalLine: (value) {
return FlLine(
return const FlLine(
color: Color.fromRGBO(209, 213, 219, 1),
strokeWidth: 2,
dashArray: [5, 5],
......@@ -59,17 +94,21 @@ class TemperatureCharBlock extends StatelessWidget {
},
),
titlesData: FlTitlesData(
rightTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
topTitles: AxisTitles(sideTitles: SideTitles(showTitles: false)),
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
interval: 6,
interval: _bottomInterval,
getTitlesWidget: (value, meta) {
return Text(
'11:04',
_formatBottomTitle(value),
style: TextStyle(
color: Color.fromRGBO(156, 163, 175, 1),
color: const Color.fromRGBO(156, 163, 175, 1),
fontSize: 14.sp,
),
);
......@@ -80,12 +119,12 @@ class TemperatureCharBlock extends StatelessWidget {
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
interval: 20,
interval: _horizontalInterval,
getTitlesWidget: (value, meta) {
return Text(
'${value.toInt()}',
style: TextStyle(
color: Color.fromRGBO(156, 163, 175, 1),
color: const Color.fromRGBO(156, 163, 175, 1),
fontSize: 14.sp,
),
);
......@@ -95,21 +134,21 @@ class TemperatureCharBlock extends StatelessWidget {
),
),
borderData: FlBorderData(show: false),
minX: 0,
maxX: 24,
minY: 0,
maxY: 100,
minX: _minX,
maxX: _maxX,
minY: _minY,
maxY: _maxY,
lineBarsData: [
LineChartBarData(
spots: alarmInfo.temperatureSpots,
isCurved: true,
color: Color.fromRGBO(239, 68, 68, 1),
color: const Color.fromRGBO(239, 68, 68, 1),
barWidth: 4,
isStrokeCapRound: true,
dotData: FlDotData(show: false),
dotData: const FlDotData(show: false),
belowBarData: BarAreaData(
show: true,
gradient: LinearGradient(
gradient: const LinearGradient(
colors: [
Color.fromRGBO(254, 202, 202, 1),
Color.fromRGBO(254, 226, 226, 0.1),
......
......@@ -8,7 +8,8 @@ class EnergyCubit extends Cubit<EnergyState> {
final DashboardService _service;
EnergyCubit({DashboardService? service})
: _service = service ?? DashboardService(repository: DashboardRepository()),
: _service =
service ?? DashboardService(repository: DashboardRepository()),
super(const EnergyState()) {
loadData();
}
......@@ -31,8 +32,7 @@ class EnergyCubit extends Cubit<EnergyState> {
// 计算今日变化百分比
double todayChange = 0;
if (data.yesterdayElectricity > 0) {
todayChange =
((data.todayElectricity - data.yesterdayElectricity) /
todayChange = ((data.todayElectricity - data.yesterdayElectricity) /
data.yesterdayElectricity) *
100;
}
......@@ -40,16 +40,14 @@ class EnergyCubit extends Cubit<EnergyState> {
// 计算本月变化百分比
double monthChange = 0;
if (data.lastMonthElectricity > 0) {
monthChange =
((data.monthElectricity - data.lastMonthElectricity) /
monthChange = ((data.monthElectricity - data.lastMonthElectricity) /
data.lastMonthElectricity) *
100;
}
// 将逐小时数据点提取为 List<double>
final hourlyData = data.hourlyUsageToday.hourlyPoints
.map((p) => p.value)
.toList();
final hourlyData =
data.hourlyUsageToday.hourlyPoints.map((p) => p.value).toList();
// 将分区数据映射为 ZoneData 列表
final totalToday = data.zoneUsageRatio.totalToday;
......@@ -69,6 +67,7 @@ class EnergyCubit extends Cubit<EnergyState> {
monthEnergy: data.monthElectricity,
monthEnergyChange: monthChange,
monthBill: data.monthCostEstimate,
hourlyMaxValue: data.hourlyUsageToday.maxValue,
hourlyData: hourlyData,
zoneData: zoneData,
);
......
......@@ -23,6 +23,7 @@ class EnergyState extends Equatable {
final double monthEnergy;
final double monthEnergyChange;
final double monthBill;
final double hourlyMaxValue;
final List<double> hourlyData;
final List<ZoneData> zoneData;
......@@ -34,10 +35,8 @@ class EnergyState extends Equatable {
this.monthEnergy = 38420,
this.monthEnergyChange = -5,
this.monthBill = 6982,
this.hourlyData = const [
45, 38, 32, 28, 25, 30, 42, 78, 112, 145, 168, 175,
162, 148, 132, 115, 98, 82, 70, 58, 48, 42, 38, 35,
],
this.hourlyMaxValue = 0,
this.hourlyData = const [],
this.zoneData = const [
ZoneData(name: '客房区域', percentage: 68, energy: 873),
ZoneData(name: '公共区域', percentage: 18, energy: 231),
......@@ -54,6 +53,7 @@ class EnergyState extends Equatable {
double? monthEnergy,
double? monthEnergyChange,
double? monthBill,
double? hourlyMaxValue,
List<double>? hourlyData,
List<ZoneData>? zoneData,
bool clearError = false,
......@@ -66,6 +66,7 @@ class EnergyState extends Equatable {
monthEnergy: monthEnergy ?? this.monthEnergy,
monthEnergyChange: monthEnergyChange ?? this.monthEnergyChange,
monthBill: monthBill ?? this.monthBill,
hourlyMaxValue: hourlyMaxValue ?? this.hourlyMaxValue,
hourlyData: hourlyData ?? this.hourlyData,
zoneData: zoneData ?? this.zoneData,
);
......@@ -80,6 +81,7 @@ class EnergyState extends Equatable {
monthEnergy,
monthEnergyChange,
monthBill,
hourlyMaxValue,
hourlyData,
zoneData,
];
......
......@@ -56,8 +56,7 @@ class ReportEnergyDetailView extends StatelessWidget {
),
SizedBox(height: 16.h),
ElevatedButton(
onPressed: () =>
context.read<EnergyCubit>().loadData(),
onPressed: () => context.read<EnergyCubit>().loadData(),
child: const Text('重试'),
),
],
......@@ -76,7 +75,10 @@ class ReportEnergyDetailView extends StatelessWidget {
monthBill: state.monthBill,
),
SizedBox(height: 16.h),
HourlyChartBlock(hourlyData: state.hourlyData),
HourlyChartBlock(
hourlyData: state.hourlyData,
maxValue: state.hourlyMaxValue,
),
SizedBox(height: 16.h),
ZoneChartBlock(zoneData: state.zoneData),
SizedBox(height: 20.h),
......
......@@ -4,8 +4,27 @@ import 'package:fl_chart/fl_chart.dart';
class HourlyChartBlock extends StatelessWidget {
final List<double> hourlyData;
final double maxValue;
const HourlyChartBlock({super.key, required this.hourlyData});
const HourlyChartBlock({
super.key,
required this.hourlyData,
required this.maxValue,
});
double get _chartMaxY {
final dataMaxValue = maxValue > 0 ? maxValue : 0.0;
final listMaxValue =
hourlyData.isEmpty ? 0.0 : hourlyData.reduce((a, b) => a > b ? a : b);
final chartMaxValue =
dataMaxValue > listMaxValue ? dataMaxValue : listMaxValue;
if (chartMaxValue <= 0) {
return 100;
}
return chartMaxValue * 1.2;
}
double get _chartInterval => _chartMaxY / 5;
@override
Widget build(BuildContext context) {
......@@ -33,7 +52,7 @@ class HourlyChartBlock extends StatelessWidget {
child: BarChart(
BarChartData(
alignment: BarChartAlignment.spaceAround,
maxY: 100,
maxY: _chartMaxY,
barTouchData: BarTouchData(enabled: false),
titlesData: FlTitlesData(
show: true,
......@@ -62,10 +81,10 @@ class HourlyChartBlock extends StatelessWidget {
gridData: FlGridData(
show: true,
drawVerticalLine: false,
horizontalInterval: 20,
horizontalInterval: _chartInterval,
getDrawingHorizontalLine: (value) {
return FlLine(
color: const Color.fromRGBO(200, 200, 200, 1),
return const FlLine(
color: Color.fromRGBO(200, 200, 200, 1),
strokeWidth: 1,
dashArray: [5, 5],
);
......@@ -93,7 +112,7 @@ class HourlyChartBlock extends StatelessWidget {
} else if (index == 24) {
text = '24:00';
} else {
text = '$index:04';
text = '${index.toString().padLeft(2, '0')}:00';
}
} else {
text = '';
......@@ -109,22 +128,9 @@ class HourlyChartBlock extends StatelessWidget {
color: Colors.black54,
fontSize: 14,
);
String text;
if (value == 0) {
text = '0';
} else if (value == 20) {
text = '20';
} else if (value == 40) {
text = '40';
} else if (value == 60) {
text = '60';
} else if (value == 80) {
text = '80';
} else if (value == 100) {
text = '100';
} else {
text = '';
}
final text = value % _chartInterval == 0
? value.toStringAsFixed(value.truncateToDouble() == value ? 0 : 1)
: '';
return SideTitleWidget(
meta: meta,
child: Text(text, style: style),
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment