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 = ["GPS", "GLONASS", "GALILEO", "BEIDOU", "QZSS"]; const signalPrefixList = ["G", "R", "E", "B", "Q"]; const List 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 { late final GnssController controller; final List signalColorList; // 接收每个组的颜色 final List QselectedSignal; // 新增变量,用于跟踪选中的信号 ChartPart({super.key}) { controller = Get.find(); } List checkSVData = []; final signalGNSS = [ controller.signalData?.GPS, controller.signalData?.GLO, controller.signalData?.GAL, controller.signalData?.BDS, controller.signalData?.QZSS, ]; double maxY = 0; int maxX = 10; double xLength = 0; int? i; // 新增变量,用于跟踪选中的按钮索引 @override void drawBarChart( Canvas canvas, Size size, int index, Paint paint, ) { if(QselectedSignal[index]){ paint.color = signalColorList[index]; for (final signal in signalGNSS[index]) { for (int i = 0; i < signals.length; i++) { SvItem item = svData[i]; if (item.l1 == 0 && item.l2 == 0 && item.l3 == 0 && item.l4 == 0 && item.l5 == 0) { continue; } maxX = max(maxX, item.sn); List 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++;} // 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 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 listy, [Color color = const Color.fromRGBO(33, 150, 243, 1)]) { List 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); } }