gnssview_old/lib/quality/chartpart.dart
2024-08-01 14:43:57 +08:00

313 lines
11 KiB
Dart
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import 'dart:math';
import 'package:flutter/material.dart';
import 'package:fl_chart/fl_chart.dart';
import 'package:get/get.dart';
import 'package:gnss/gnss.dart';
import '../Controller/gnss_controller.dart';
const signalNameList = <String>["GPS", "GLONASS", "GALILEO", "BEIDOU", "QZSS"];
const signalPrefixList = <String>["G", "R", "E", "B", "Q"];
const List<Color> signalColorList = [
Color.fromARGB(255, 255, 0, 0),
Color.fromARGB(255, 0, 255, 0),
Color.fromARGB(255, 0, 0, 255),
Color.fromARGB(255, 255, 255, 0),
Color.fromARGB(255, 0, 255, 255)
];
class ChartPart extends StatelessWidget {
final List<List<SignalGNSS>?> signalGNSS;
late final GnssController controller;
final List<Color> signalColorList; // 接收每个组的颜色
List<SignalGNSS> signalGPS = []; // 用于存储每个组的信号数据
List<bool> QselectedSignal; // 新增变量,用于跟踪选中的信号
ChartPart({super.key}) {
controller = Get.find<GnssController>();
}
List<BarChartGroupData> checkSVData = [];
double maxY = 0;
int maxX = 10;
double xLength = 0;
@override
void drawBarChart(
Canvas canvas,
Size size,
int index,
Paint paint,
) {
if(QselectedSignal[0]){
for (final signal in SignalGPS) {
for (int i = 0; i < signal.length; i++) {
SignalGPS signalGPS=signal[i];
if (signalGPS.snrL1 == 0 &&
signalGPS.snrL2 == 0 &&
signalGPS.snrL5 == 0) {
continue;
}
maxX = max(maxX, signalGPS.sn);
List<int> listy = [signalGPS.snrL1, signalGPS.snrL2, signalGPS.snrL5];
int maxItem = listy.reduce(max);
maxY = max(maxY, maxItem.toDouble());
checkSVData.add(makeGroupData(i + 1, listy, signalColorList[0]));
xLength++;}
// svData = List.from(controller.svData)
// ..sort((a, b) => a.sn.compareTo(b.sn));
// for (int i = 0; i < svData.length; i++) {
// SvItem item = svData[i];
// if (item.l1 == 0 &&
// item.l2 == 0 &&
// item.l3 == 0 &&
// item.l4 == 0 &&
// item.l5 == 0) {
// continue;
// }
// if (signalQualityItem.show &&
// (selectedIndex == null ||
// selectedIndex ==
// controller.signalQuality.keys.toList().indexOf(sys))) {
// maxX = max(maxX, item.sn);
// List<int> listy = [item.l1, item.l2, item.l3, item.l4, item.l5];
// int maxItem = listy.reduce(max);
// maxY = max(maxY, maxItem.toDouble());
// checkSVData.add(makeGroupData(i + 1, listy, signalQualityItem.color));
// xLength++;
// }
// }
// // print('CheckSVData: $checkSVData'); // 调试输出
// if (checkSVData.isNotEmpty) {
// if (controller.startIndex.value < checkSVData.length - 8) {
// checkSVData = checkSVData.sublist(
// controller.startIndex.value, controller.startIndex.value + 8);
// } else {
// checkSVData = checkSVData.sublist(
// controller.startIndex.value, checkSVData.length - 1);
// }
// }
// }
// @override
// Widget build(BuildContext context) {
// // 只有当选中状态不为空时才更新数据
// if (selectedIndex != null) {
// updateSVdata();
// }
// ever(controller.startIndex, (callback) {
// if (svData.length - callback < 8) {
// controller.startIndex.value = max(0, svData.length - 8); // 确保不小于 0
// return;
// }
// updateSVdata();
// });
final size = MediaQuery.of(context).size;
final orientation =
MediaQuery.of(context).orientation == Orientation.portrait;
return SizedBox(
width: size.width,
// decoration: const BoxDecoration(color: Colors.white),
child: AspectRatio(
aspectRatio: 1,
child: Padding(
padding: const EdgeInsets.all(10),
child: Stack(
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.stretch,
children: [
Expanded(
child: Obx(() {
controller.startIndex.value;
return BarChart(
swapAnimationDuration: const Duration(milliseconds: 0),
BarChartData(
maxY: maxY, // 提示需要+ 20 因为 提示是根据柱状图位置进行计算的
barTouchData: BarTouchData(
enabled: false,
touchTooltipData: BarTouchTooltipData(
// tooltipBgColor: Colors.blueGrey,
getTooltipItem: (
BarChartGroupData group,
int groupIndex,
BarChartRodData rod,
int rodIndex,
) {
return BarTooltipItem(
'L1:${group.barRods[0].toY}\n',
const TextStyle(
fontWeight: FontWeight.bold,
decoration: TextDecoration.none,
color: Colors.black,
fontSize: 18,
shadows: [
Shadow(
color: Colors.black26,
blurRadius: 12,
)
],
),
);
},
),
touchCallback: (event, response) {
if (event.isInterestedForInteractions &&
response != null &&
response.spot != null) {
// setState(() {
// touchedGroupIndex =
// response.spot!.touchedBarGroupIndex;
// });
} else {
// setState(() {
// touchedGroupIndex = -100;
// });
}
},
),
titlesData: FlTitlesData(
show: true,
rightTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
topTitles: const AxisTitles(
sideTitles: SideTitles(showTitles: false),
),
bottomTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
getTitlesWidget: bottomTitles,
reservedSize: 42,
),
),
leftTitles: AxisTitles(
sideTitles: SideTitles(
showTitles: true,
reservedSize: 40,
interval: 1,
getTitlesWidget: leftTitles,
),
),
),
borderData: FlBorderData(
show: false,
),
barGroups: checkSVData,
gridData: const FlGridData(show: true),
),
);
}),
),
orientation
? const SizedBox(
height: 50,
)
: const Text(""),
],
),
Positioned(
bottom: 0,
left: 0,
right: 0,
height: size.height,
child: Opacity(
opacity: 0, // 设置 Slider 组件的透明度为 0使其不可见
child: Slider(
value: controller.startIndex.toDouble(),
onChanged: (newvalue) {
controller.updateSlider(newvalue);
},
min: 0,
max: xLength <= 5 ? 0 : xLength - 5,
),
),
),
],
),
),
),
);
}
Widget leftTitles(double value, TitleMeta meta) {
const style = TextStyle(
color: Color(0xff7589a2),
fontWeight: FontWeight.bold,
fontSize: 14,
decoration: TextDecoration.none);
String text;
int intValue = (value).ceil();
if (intValue % 10 == 0 && intValue <= maxY) {
text = intValue.toString();
} else {
return Container();
}
return SideTitleWidget(
axisSide: meta.axisSide,
space: 0,
child: Padding(
padding: const EdgeInsets.only(right: 20),
child: Text(text, style: style)),
);
}
Map svMap = {
"BEIDOU": "BSV",
"GLONASS": "ESV",
"GPS": "GSV",
"GALILEO": "RSV",
};
Widget bottomTitles(double index, TitleMeta meta) {
String text = "";
int intValue = (index - 1).ceil();
if (svData.isNotEmpty) {
var data = svData[intValue];
String? name = svMap[data.name];
if (name != null) {
text = "${name.substring(0, 1)}${data.sn}";
}
}
return SideTitleWidget(
axisSide: meta.axisSide,
space: 10, //margin top
child: Text(
text,
style: const TextStyle(
color: Color(0xff7589a2),
fontWeight: FontWeight.bold,
decoration: TextDecoration.none,
fontSize: 14,
),
textAlign: TextAlign.left,
),
);
}
final double width = 15;
final Color leftBarColor = const Color.fromARGB(95, 101, 98, 98);
final Color rightBarColor = const Color.fromRGBO(33, 150, 243, 1);
BarChartGroupData makeGroupData(int x, List<int> listy,
[Color color = const Color.fromRGBO(33, 150, 243, 1)]) {
List<BarChartRodData> list = [];
for (var i = 0; i < listy.length; i++) {
list.add(BarChartRodData(
toY: listy[i].toDouble(),
color: color.withOpacity((i + 1) * .2),
borderRadius: const BorderRadius.all(
Radius.circular(2),
),
width: width,
));
}
return BarChartGroupData(
barsSpace: 0, x: x, showingTooltipIndicators: [], barRods: list);
}
}