import 'dart:async'; import 'dart:convert'; import 'dart:math'; import 'package:flutter/material.dart'; import 'package:fl_chart/fl_chart.dart'; import 'package:get/get.dart'; import 'package:get/get_state_manager/get_state_manager.dart'; import 'package:gnss/gnss.dart'; import '../Controller/gnss_controller.dart'; List> signalColorList = [ { 'L1': Color.fromARGB(255, 255, 0, 0), 'L2': Color.fromARGB(255, 0, 255, 0), 'L5': Color.fromARGB(255, 0, 0, 255) }, {'G1': Color.fromARGB(255, 255, 0, 0), 'G2': Color.fromARGB(255, 0, 255, 0)}, { 'E5a': Color.fromARGB(255, 255, 0, 0), 'E5b': Color.fromARGB(255, 0, 255, 0), 'L1-BC': Color.fromARGB(255, 0, 0, 255) }, { 'B1I': Color.fromARGB(255, 255, 0, 0), 'B3I': Color.fromARGB(255, 0, 255, 0), 'B2I': Color.fromARGB(255, 0, 0, 255) }, { 'L1': Color.fromARGB(255, 255, 0, 0), 'L2': Color.fromARGB(255, 0, 255, 0), 'L5': Color.fromARGB(255, 0, 0, 255) }, ]; const signalNameList = ["GPS", "GLO", "GAL", "BDS", "QZS"]; class ChartPart extends GetView { ChartPart({super.key}); // List signalGNSS = []; // final double baselineX; final double maxY = 70; // final int maxX = 10; @override Widget build(BuildContext context) { final size = MediaQuery.of(context).size; double xLength = 0; final orientation = MediaQuery.of(context).orientation == Orientation.portrait; return Obx(() { controller.signalUpdate.value; controller.baselineX.value; var key = controller.qselectedSystem.value; List signalGNSS = []; Map signalColorMap = {}; int index = signalNameList.indexOf(key); if (index >= 0 && index < signalColorList.length) { signalColorMap = signalColorList[index]; } if (controller.signalData != null && controller.signalData!.containsKey(key)) { signalGNSS = controller.signalData![key]!; } // List prnList = signalGNSS.map((signal) => signal.prn).toList(); // // // for (var i = 0; i < signalGNSS.length; i++) {} 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: BarChart( swapAnimationDuration: const Duration(milliseconds: 0), BarChartData( maxY: 70, // 提示需要+ 20 因为 提示是根据柱状图位置进行计算的 alignment: BarChartAlignment.start, 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: List.generate( (signalGNSS.length - controller.baselineX.value.toInt()) .clamp(0, 12), (id) { // List groupData = []; index = id + controller.baselineX.value.toInt(); List listy = []; List ColorList = []; var snr = signalGNSS[index].snr; snr.forEach((key, value) { listy.add(value); ColorList.add(signalColorMap[key] ?? Colors.yellow); }); return makeGroupData(index, listy, ColorList); }), gridData: const FlGridData(show: true), groupsSpace: 50, ), )), orientation ? const SizedBox( height: 50, ) : const Text(""), ], ), Positioned( bottom: 0, left: 0, right: 0, height: size.height, child: signalGNSS.length > 12 // 只有当数据长度大于12时才显示滑块 ? Opacity( opacity: 0, child: Slider( value: controller.baselineX.toDouble(), onChanged: (newvalue) { controller.updateSlider(newvalue); }, min: 0, max: (signalGNSS.length - 12) .toDouble(), // 设置最大值为 signalGNSS.length - 12 )) : Container(), // 否则显示一个空的容器 ), Positioned( top: 0, right: 10, child: Row( crossAxisAlignment: CrossAxisAlignment.start, children: signalColorMap.entries.map((entry) { return Padding( padding: const EdgeInsets.only(right: 10.0), // 设置右侧的间距 child: Column( children: [ Container( width: 20, height: 20, color: entry.value, ), const SizedBox(width: 5), Text( entry.key, style: const TextStyle( color: Colors.black, fontWeight: FontWeight.bold, fontSize: 14, decoration: TextDecoration.none, ), ), ], ), ); }).toList(), ), ), ], ), ), ), ); }); } Widget leftTitles(double value, TitleMeta meta) { print("value: $value"); const style = TextStyle( color: Color(0xff7589a2), fontWeight: FontWeight.bold, fontSize: 14, decoration: TextDecoration.none); String text; int intValue = value.toInt(); if (intValue % 10 == 0 && intValue < maxY) { text = intValue.toString(); print("intValue: $intValue, maxY: $maxY"); } else { return Container(); } return SideTitleWidget( axisSide: meta.axisSide, space: 0, child: Padding( padding: const EdgeInsets.only(right: 20), child: Text(text, style: style)), ); } Map signalPrefix = { "GPS": "G", "GLO": "R", "GAL": "E", "BDS": "B", "QZS": "Q", }; Widget bottomTitles(double index, TitleMeta meta) { final signalGNSS = controller.signalData![controller.qselectedSystem.value]!; String text = ""; int intValue = (index).ceil(); var key = controller.qselectedSystem.value; String? name = signalPrefix[key]; var data = signalGNSS[intValue].prn; List.generate(signalGNSS.length, (index) { text = "${name}${data}"; }); 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, List ColorList) { List list = []; for (var i = 0; i < listy.length; i++) { // Color color = signalColorList[i]; list.add(BarChartRodData( toY: listy[i].toDouble(), // color: color.withOpacity((i + 1) * .2), color: ColorList[i], borderRadius: const BorderRadius.all( Radius.circular(2), ), width: width, )); } return BarChartGroupData( barsSpace: 0, x: x, showingTooltipIndicators: [], barRods: list); } }