diff --git a/lib/services/nt_widget_builder.dart b/lib/services/nt_widget_builder.dart index 8ac79a52..111fc366 100644 --- a/lib/services/nt_widget_builder.dart +++ b/lib/services/nt_widget_builder.dart @@ -120,9 +120,9 @@ class NTWidgetBuilder { minHeight: _normalSize); registerWithAlias( - names: {RadialGauge.widgetType, 'Simple Dial'}, + names: {RadialGaugeWidget.widgetType, 'Simple Dial'}, model: RadialGaugeModel.new, - widget: RadialGauge.new, + widget: RadialGaugeWidget.new, fromJson: RadialGaugeModel.fromJson, minWidth: _normalSize * 1.6, minHeight: _normalSize * 1.6); diff --git a/lib/widgets/nt_widgets/multi-topic/differential_drive.dart b/lib/widgets/nt_widgets/multi-topic/differential_drive.dart index c21428b9..5a43f7cc 100644 --- a/lib/widgets/nt_widgets/multi-topic/differential_drive.dart +++ b/lib/widgets/nt_widgets/multi-topic/differential_drive.dart @@ -3,8 +3,8 @@ import 'dart:math'; import 'package:flutter/material.dart'; import 'package:dot_cast/dot_cast.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/widgets/nt_widgets/nt_widget.dart'; @@ -112,26 +112,36 @@ class DifferentialDrive extends NTWidget { mainAxisSize: MainAxisSize.min, children: [ // Left speed gauge - SfLinearGauge( - key: UniqueKey(), - maximum: 1.0, - minimum: -1.0, - labelPosition: LinearLabelPosition.inside, - tickPosition: LinearElementPosition.inside, - markerPointers: [ - LinearShapePointer( + LinearGauge( + rulers: RulerStyle( + rulerPosition: RulerPosition.right, + showLabel: true, + textStyle: Theme.of(context).textTheme.bodySmall, + primaryRulerColor: Colors.grey, + secondaryRulerColor: Colors.grey, + labelOffset: 5, + ), + extendLinearGauge: 1, + linearGaugeBoxDecoration: const LinearGaugeBoxDecoration( + backgroundColor: Color.fromRGBO(87, 87, 87, 1), + thickness: 7.5, + borderRadius: 10, + ), + pointers: [ + Pointer( + key: UniqueKey(), + enableAnimation: false, value: model.leftSpeedCurrentValue.value.clamp(-1.0, 1.0), + shape: PointerShape.triangle, color: Theme.of(context).colorScheme.primary, - height: 12.5, + pointerPosition: PointerPosition.left, width: 12.5, - animationDuration: 0, - shapeType: LinearShapePointerType.invertedTriangle, - position: LinearElementPosition.outside, - dragBehavior: LinearMarkerDragBehavior.free, + height: 12.5, + isInteractive: true, onChanged: (value) { model.leftSpeedCurrentValue.value = value; }, - onChangeEnd: (value) { + onChangeEnd: () { bool publishTopic = model.leftSpeedTopic == null; model.leftSpeedTopic ??= model.ntConnection @@ -151,17 +161,15 @@ class DifferentialDrive extends NTWidget { model.leftSpeedPreviousValue = model.leftSpeedCurrentValue.value; }, - ), + ) ], - axisTrackStyle: const LinearAxisTrackStyle( - thickness: 7.5, - edgeStyle: LinearEdgeStyle.bothCurve, - ), - orientation: LinearGaugeOrientation.vertical, - interval: 0.5, - minorTicksPerInterval: 2, + gaugeOrientation: GaugeOrientation.vertical, + start: -1.0, + end: 1.0, + steps: 0.5, + enableGaugeAnimation: false, ), - const SizedBox(width: 5), + const SizedBox(width: 15), // Robot Flexible( child: LayoutBuilder( @@ -184,28 +192,38 @@ class DifferentialDrive extends NTWidget { }, ), ), - const SizedBox(width: 5), + const SizedBox(width: 15), // Right speed gauge - SfLinearGauge( - key: UniqueKey(), - maximum: 1.0, - minimum: -1.0, - labelPosition: LinearLabelPosition.outside, - tickPosition: LinearElementPosition.outside, - markerPointers: [ - LinearShapePointer( + LinearGauge( + rulers: RulerStyle( + rulerPosition: RulerPosition.left, + showLabel: true, + textStyle: Theme.of(context).textTheme.bodySmall, + primaryRulerColor: Colors.grey, + secondaryRulerColor: Colors.grey, + labelOffset: 5, + ), + extendLinearGauge: 1, + linearGaugeBoxDecoration: const LinearGaugeBoxDecoration( + backgroundColor: Color.fromRGBO(87, 87, 87, 1), + thickness: 7.5, + borderRadius: 10, + ), + pointers: [ + Pointer( + key: UniqueKey(), + enableAnimation: false, value: model.rightSpeedCurrentValue.value.clamp(-1.0, 1.0), + shape: PointerShape.triangle, color: Theme.of(context).colorScheme.primary, - height: 12.5, + pointerPosition: PointerPosition.right, width: 12.5, - animationDuration: 0, - shapeType: LinearShapePointerType.triangle, - position: LinearElementPosition.inside, - dragBehavior: LinearMarkerDragBehavior.free, + height: 12.5, + isInteractive: true, onChanged: (value) { model.rightSpeedCurrentValue.value = value; }, - onChangeEnd: (value) { + onChangeEnd: () { bool publishTopic = model.rightSpeedTopic == null; model.rightSpeedTopic ??= model.ntConnection @@ -227,12 +245,11 @@ class DifferentialDrive extends NTWidget { }, ), ], - axisTrackStyle: const LinearAxisTrackStyle( - thickness: 7.5, - edgeStyle: LinearEdgeStyle.bothCurve, - ), - orientation: LinearGaugeOrientation.vertical, - interval: 0.5, + gaugeOrientation: GaugeOrientation.vertical, + start: -1.0, + end: 1.0, + steps: 0.5, + enableGaugeAnimation: false, ), ], ); diff --git a/lib/widgets/nt_widgets/multi-topic/gyro.dart b/lib/widgets/nt_widgets/multi-topic/gyro.dart index c675ecf6..4314b68d 100644 --- a/lib/widgets/nt_widgets/multi-topic/gyro.dart +++ b/lib/widgets/nt_widgets/multi-topic/gyro.dart @@ -1,8 +1,10 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:dot_cast/dot_cast.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/widgets/dialog_widgets/dialog_toggle_switch.dart'; @@ -107,40 +109,63 @@ class Gyro extends NTWidget { return Column( children: [ Flexible( - child: SfRadialGauge( - axes: [ - RadialAxis( - pointers: [ - NeedlePointer( - value: angle, - needleColor: Colors.red, - needleEndWidth: 5, - needleStartWidth: 1, - needleLength: 0.7, - knobStyle: const KnobStyle( - borderColor: Colors.grey, - borderWidth: 0.025, + child: LayoutBuilder(builder: (context, constraints) { + double squareSide = + min(constraints.maxWidth, constraints.maxHeight); + + // Formula taken from radial gauge source code + final maxNeedleHeight = squareSide / (2 * 0.65) - (2 * 7.5); + return Stack( + alignment: Alignment.center, + children: [ + RadialGauge( + radiusFactor: 0.65, + track: RadialTrack( + thickness: 7.5, + start: 0, + end: 360, + startAngle: 90, + endAngle: 90 + 360, + steps: 360 ~/ 45, + color: const Color.fromRGBO(97, 97, 97, 1), + trackStyle: TrackStyle( + primaryRulerColor: Colors.grey, + secondaryRulerColor: + const Color.fromRGBO(97, 97, 97, 1), + labelStyle: Theme.of(context).textTheme.bodySmall, + primaryRulersHeight: 7.5, + primaryRulersWidth: 2, + secondaryRulersHeight: 7.5, + rulersOffset: -18, + labelOffset: -57.5, + showLastLabel: false, + secondaryRulerPerInterval: 8, + inverseRulers: true), + trackLabelFormater: (value) => value.toStringAsFixed(0), + ), + needlePointer: [ + NeedlePointer( + needleWidth: squareSide * 0.03, + needleEndWidth: squareSide * 0.005, + needleHeight: maxNeedleHeight * 0.52 - + (squareSide - 175.875) * 0.075, + tailColor: Colors.grey, + tailRadius: squareSide * 0.1, + value: value, ), - ) - ], - axisLineStyle: const AxisLineStyle( - thickness: 5, + ], ), - axisLabelStyle: const GaugeTextStyle( - fontSize: 14, + Container( + width: squareSide * 0.07, + height: squareSide * 0.07, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.grey[300]!, + ), ), - ticksPosition: ElementsPosition.outside, - labelsPosition: ElementsPosition.outside, - showTicks: true, - minorTicksPerInterval: 8, - interval: 45, - minimum: 0, - maximum: 360, - startAngle: 270, - endAngle: 270, - ) - ], - ), + ], + ); + }), ), Text(angle.toStringAsFixed(2), style: Theme.of(context).textTheme.bodyLarge), diff --git a/lib/widgets/nt_widgets/multi-topic/motor_controller.dart b/lib/widgets/nt_widgets/multi-topic/motor_controller.dart index 27822a40..4ba1b995 100644 --- a/lib/widgets/nt_widgets/multi-topic/motor_controller.dart +++ b/lib/widgets/nt_widgets/multi-topic/motor_controller.dart @@ -1,8 +1,8 @@ import 'package:flutter/material.dart'; import 'package:dot_cast/dot_cast.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/widgets/nt_widgets/nt_widget.dart'; @@ -63,21 +63,32 @@ class MotorController extends NTWidget { const Flexible( child: SizedBox(height: 5), ), - SfLinearGauge( - maximum: 1.0, - minimum: -1.0, - markerPointers: [ - LinearShapePointer( + LinearGauge( + rulers: RulerStyle( + rulerPosition: RulerPosition.bottom, + primaryRulerColor: Colors.grey, + secondaryRulerColor: Colors.grey, + textStyle: Theme.of(context).textTheme.bodySmall, + ), + extendLinearGauge: 1, + linearGaugeBoxDecoration: const LinearGaugeBoxDecoration( + backgroundColor: Color.fromRGBO(87, 87, 87, 1), + thickness: 5, + ), + pointers: [ + Pointer( + enableAnimation: false, value: value.clamp(-1.0, 1.0), + shape: PointerShape.diamond, color: Theme.of(context).colorScheme.primary, width: 10.0, height: 14.0, - enableAnimation: false, - shapeType: LinearShapePointerType.diamond, - position: LinearElementPosition.cross, - ), + ) ], - interval: 0.5, + enableGaugeAnimation: false, + start: -1.0, + end: 1.0, + steps: 0.5, ), ], ); diff --git a/lib/widgets/nt_widgets/nt_widget.dart b/lib/widgets/nt_widgets/nt_widget.dart index 2f1542d3..aceefc50 100644 --- a/lib/widgets/nt_widgets/nt_widget.dart +++ b/lib/widgets/nt_widgets/nt_widget.dart @@ -185,7 +185,7 @@ class SingleTopicNTWidgetModel extends NTWidgetModel { NumberBar.widgetType, NumberSlider.widgetType, VoltageView.widgetType, - RadialGauge.widgetType, + RadialGaugeWidget.widgetType, GraphWidget.widgetType, MatchTimeWidget.widgetType, ]; diff --git a/lib/widgets/nt_widgets/single_topic/number_bar.dart b/lib/widgets/nt_widgets/single_topic/number_bar.dart index 97e2a391..291573df 100644 --- a/lib/widgets/nt_widgets/single_topic/number_bar.dart +++ b/lib/widgets/nt_widgets/single_topic/number_bar.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:dot_cast/dot_cast.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/services/text_formatter_builder.dart'; @@ -206,6 +206,9 @@ class NumberBar extends NTWidget { Widget build(BuildContext context) { NumberBarModel model = cast(context.watch()); + String formatLabel(num input) => + input.toStringAsFixed(input.truncateToDouble() == input ? 0 : 2); + return ValueListenableBuilder( valueListenable: model.subscription!, builder: (context, data, child) { @@ -219,10 +222,14 @@ class NumberBar extends NTWidget { int fractionDigits = (model.dataType == NT4TypeStr.kInt) ? 0 : 2; - LinearGaugeOrientation gaugeOrientation = - (model.orientation == 'vertical') - ? LinearGaugeOrientation.vertical - : LinearGaugeOrientation.horizontal; + GaugeOrientation gaugeOrientation = (model.orientation == 'vertical') + ? GaugeOrientation.vertical + : GaugeOrientation.horizontal; + + RulerPosition rulerPosition = + (gaugeOrientation == GaugeOrientation.vertical) + ? RulerPosition.right + : RulerPosition.bottom; List children = [ Text( @@ -233,29 +240,43 @@ class NumberBar extends NTWidget { const Flexible( child: SizedBox(width: 5.0, height: 5.0), ), - SfLinearGauge( + LinearGauge( key: UniqueKey(), - maximum: model.maxValue, - minimum: model.minValue, - barPointers: [ - LinearBarPointer( + rulers: RulerStyle( + rulerPosition: rulerPosition, + inverseRulers: model.inverted, + showLabel: true, + textStyle: Theme.of(context).textTheme.bodyMedium, + primaryRulerColor: Colors.grey, + secondaryRulerColor: Colors.grey, + ), + gaugeOrientation: gaugeOrientation, + valueBar: [ + ValueBar( + color: Theme.of(context).colorScheme.primary, value: clampedValue, + borderRadius: 5, + valueBarThickness: 7.5, + enableAnimation: false, animationDuration: 0, - thickness: 7.5, - edgeStyle: LinearEdgeStyle.bothCurve, ), ], - axisTrackStyle: const LinearAxisTrackStyle( - thickness: 7.5, - edgeStyle: LinearEdgeStyle.bothCurve, - ), - orientation: gaugeOrientation, - isAxisInversed: model.inverted, - interval: divisionInterval, + customLabels: [ + if (model.divisions != null) + for (int i = 0; i < model.divisions!; i++) + CustomRulerLabel( + text: formatLabel(model.minValue + divisionInterval! * i), + value: model.minValue + divisionInterval * i, + ), + ], + enableGaugeAnimation: false, + start: model.minValue, + end: model.maxValue, + steps: divisionInterval, ), ]; - if (gaugeOrientation == LinearGaugeOrientation.vertical) { + if (gaugeOrientation == GaugeOrientation.vertical) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: children, diff --git a/lib/widgets/nt_widgets/single_topic/number_slider.dart b/lib/widgets/nt_widgets/single_topic/number_slider.dart index ac4a897b..adbf5456 100644 --- a/lib/widgets/nt_widgets/single_topic/number_slider.dart +++ b/lib/widgets/nt_widgets/single_topic/number_slider.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:dot_cast/dot_cast.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/services/text_formatter_builder.dart'; @@ -227,27 +227,28 @@ class NumberSlider extends NTWidget { overflow: TextOverflow.ellipsis, ), Expanded( - child: SfLinearGauge( - key: UniqueKey(), - minimum: model.minValue, - maximum: model.maxValue, - labelPosition: LinearLabelPosition.inside, - tickPosition: LinearElementPosition.cross, - interval: divisionSeparation, - axisTrackStyle: const LinearAxisTrackStyle( - edgeStyle: LinearEdgeStyle.bothCurve, + child: LinearGauge( + rulers: RulerStyle( + rulerPosition: RulerPosition.bottom, + showLabel: true, + textStyle: Theme.of(context).textTheme.bodyMedium, + primaryRulerColor: Colors.grey, + secondaryRulerColor: Colors.grey, ), - markerPointers: [ - LinearShapePointer( - value: model.displayValue.value, + extendLinearGauge: 1, + linearGaugeBoxDecoration: const LinearGaugeBoxDecoration( + backgroundColor: Color.fromRGBO(87, 87, 87, 1), + thickness: 5, + ), + pointers: [ + Pointer( color: Theme.of(context).colorScheme.primary, - height: 15.0, - width: 15.0, - animationDuration: 0, - shapeType: LinearShapePointerType.circle, - position: LinearElementPosition.cross, - dragBehavior: LinearMarkerDragBehavior.free, - onChangeStart: (_) { + value: model.displayValue.value, + shape: PointerShape.circle, + enableAnimation: false, + height: 15, + isInteractive: true, + onChangeStart: () { model.dragging.value = true; }, onChanged: (value) { @@ -261,13 +262,24 @@ class NumberSlider extends NTWidget { model.publishValue(model.displayValue.value); } }, - onChangeEnd: (value) { + onChangeEnd: () { model.publishValue(model.displayValue.value); - model.dragging.value = false; }, ), ], + customLabels: [ + for (int i = 0; i < model.divisions; i++) + CustomRulerLabel( + text: (model.minValue + divisionSeparation * i) + .toStringAsFixed(2), + value: model.minValue + divisionSeparation * i, + ), + ], + enableGaugeAnimation: false, + start: model.minValue, + end: model.maxValue, + steps: divisionSeparation, ), ), ], diff --git a/lib/widgets/nt_widgets/single_topic/radial_gauge.dart b/lib/widgets/nt_widgets/single_topic/radial_gauge.dart index 2bb42042..d417cdbd 100644 --- a/lib/widgets/nt_widgets/single_topic/radial_gauge.dart +++ b/lib/widgets/nt_widgets/single_topic/radial_gauge.dart @@ -1,9 +1,11 @@ +import 'dart:math'; + import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:dot_cast/dot_cast.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/services/text_formatter_builder.dart'; @@ -13,7 +15,7 @@ import 'package:elastic_dashboard/widgets/nt_widgets/nt_widget.dart'; class RadialGaugeModel extends SingleTopicNTWidgetModel { @override - String type = RadialGauge.widgetType; + String type = RadialGaugeWidget.widgetType; double _startAngle = -140.0; double _endAngle = 140.0; @@ -275,10 +277,10 @@ class RadialGaugeModel extends SingleTopicNTWidgetModel { } } -class RadialGauge extends NTWidget { +class RadialGaugeWidget extends NTWidget { static const String widgetType = 'Radial Gauge'; - const RadialGauge({super.key}); + const RadialGaugeWidget({super.key}); static double _getWrappedValue(double value, double min, double max) { if (value >= min && value <= max) { @@ -310,64 +312,83 @@ class RadialGauge extends NTWidget { value = _getWrappedValue(value, model.minValue, model.maxValue); } + value = value.clamp(model.minValue, model.maxValue); + int fractionDigits = (model.dataType == NT4TypeStr.kInt) ? 0 : 2; - return SfRadialGauge( - axes: [ - RadialAxis( - startAngle: model.startAngle - 90.0, - endAngle: model.endAngle - 90.0, - minimum: model.minValue, - maximum: model.maxValue, - showTicks: model.showTicks, - showLabels: model.numberOfLabels != 0, - interval: (model.numberOfLabels != 0) - ? (model.maxValue - model.minValue) / model.numberOfLabels - : null, - showLastLabel: _getWrappedValue( - model.endAngle - model.startAngle, -180.0, 180.0) != - 0.0, - canScaleToFit: true, - annotations: [ - GaugeAnnotation( - horizontalAlignment: GaugeAlignment.center, - verticalAlignment: GaugeAlignment.center, - angle: 90.0, - positionFactor: (model.showPointer) ? 0.35 : 0.05, - widget: Text( - value.toStringAsFixed(fractionDigits), - style: TextStyle( - fontSize: (model.showPointer) ? 18.0 : 28.0, + return LayoutBuilder( + builder: (context, constraints) { + double squareSide = + min(constraints.maxWidth, constraints.maxHeight); + + return Stack( + alignment: Alignment.center, + children: [ + RadialGauge( + track: RadialTrack( + start: model.minValue, + end: model.maxValue, + startAngle: model.startAngle + 90, + endAngle: model.endAngle + 90, + steps: model.numberOfLabels, + color: const Color.fromRGBO(97, 97, 97, 1), + trackStyle: TrackStyle( + primaryRulerColor: Colors.grey, + secondaryRulerColor: Colors.grey, + showPrimaryRulers: model.showTicks, + showSecondaryRulers: model.showTicks, + labelStyle: Theme.of(context).textTheme.bodySmall, + primaryRulersHeight: model.showTicks ? 10 : 0, + secondaryRulersHeight: model.showTicks ? 8 : 0, + rulersOffset: -5, + labelOffset: -10, + showLastLabel: _getWrappedValue( + model.endAngle - model.startAngle, + -180.0, + 180.0) != + 0.0, ), - textAlign: TextAlign.center, + trackLabelFormater: (value) => + num.parse(value.toStringAsFixed(2)).toString(), ), - ), - ], - pointers: [ - RangePointer( - enableAnimation: false, - enableDragging: false, - color: Theme.of(context).colorScheme.primaryContainer, - value: value, + needlePointer: [ + if (model.showPointer) + NeedlePointer( + needleWidth: squareSide * 0.02, + needleEndWidth: squareSide * 0.004, + needleHeight: squareSide * 0.25, + tailColor: Colors.grey, + tailRadius: squareSide * 0.075, + value: value, + ), + ], + valueBar: [ + RadialValueBar( + color: Theme.of(context).colorScheme.primaryContainer, + value: value, + startPosition: (model.minValue < 0.0) ? 0.0 : null, + ), + ], ), if (model.showPointer) - NeedlePointer( - enableAnimation: false, - enableDragging: false, - needleColor: Colors.red, - needleEndWidth: 3.5, - needleStartWidth: 0.5, - needleLength: 0.5, - knobStyle: const KnobStyle( - borderColor: Colors.grey, - borderWidth: 0.025, - knobRadius: 0.05, + Container( + width: squareSide * 0.05, + height: squareSide * 0.05, + decoration: BoxDecoration( + shape: BoxShape.circle, + color: Colors.grey[300]!, ), - value: value, ), + Positioned( + bottom: squareSide * 0.3, + child: Text( + value.toStringAsFixed(fractionDigits), + style: Theme.of(context).textTheme.bodyLarge, + ), + ), ], - ), - ], + ); + }, ); }, ); diff --git a/lib/widgets/nt_widgets/single_topic/voltage_view.dart b/lib/widgets/nt_widgets/single_topic/voltage_view.dart index 13174a29..3d07c69f 100644 --- a/lib/widgets/nt_widgets/single_topic/voltage_view.dart +++ b/lib/widgets/nt_widgets/single_topic/voltage_view.dart @@ -2,8 +2,8 @@ import 'package:flutter/material.dart'; import 'package:flutter/services.dart'; import 'package:dot_cast/dot_cast.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/services/text_formatter_builder.dart'; @@ -206,6 +206,9 @@ class VoltageView extends NTWidget { Widget build(BuildContext context) { VoltageViewModel model = cast(context.watch()); + String formatLabel(num input) => + input.toStringAsFixed(input.truncateToDouble() == input ? 0 : 2); + return ValueListenableBuilder( valueListenable: model.subscription!, builder: (context, data, child) { @@ -219,10 +222,14 @@ class VoltageView extends NTWidget { int fractionDigits = (model.dataType == NT4TypeStr.kInt) ? 0 : 2; - LinearGaugeOrientation gaugeOrientation = - (model.orientation == 'vertical') - ? LinearGaugeOrientation.vertical - : LinearGaugeOrientation.horizontal; + GaugeOrientation gaugeOrientation = (model.orientation == 'vertical') + ? GaugeOrientation.vertical + : GaugeOrientation.horizontal; + + RulerPosition rulerPosition = + (gaugeOrientation == GaugeOrientation.vertical) + ? RulerPosition.right + : RulerPosition.bottom; List children = [ Text( @@ -233,29 +240,44 @@ class VoltageView extends NTWidget { const Flexible( child: SizedBox(width: 5.0, height: 5.0), ), - SfLinearGauge( + LinearGauge( key: UniqueKey(), - maximum: model.maxValue, - minimum: model.minValue, - barPointers: [ - LinearBarPointer( + rulers: RulerStyle( + rulerPosition: rulerPosition, + inverseRulers: model.inverted, + showLabel: true, + textStyle: Theme.of(context).textTheme.bodyMedium, + primaryRulerColor: Colors.grey, + secondaryRulerColor: Colors.grey, + ), + gaugeOrientation: gaugeOrientation, + valueBar: [ + ValueBar( + color: Colors.yellow, value: clampedVoltage, - color: Colors.yellow.shade600, + borderRadius: 5, + valueBarThickness: 7.5, + enableAnimation: false, animationDuration: 0, - thickness: 7.5, ), ], - axisTrackStyle: const LinearAxisTrackStyle( - thickness: 7.5, - ), - labelFormatterCallback: (value) => '$value V', - orientation: gaugeOrientation, - isAxisInversed: model.inverted, - interval: divisionInterval, + customLabels: [ + if (model.divisions != null) + for (int i = 0; i < model.divisions!; i++) + CustomRulerLabel( + text: + '${formatLabel(model.minValue + divisionInterval! * i)} V', + value: model.minValue + divisionInterval * i, + ), + ], + enableGaugeAnimation: false, + start: model.minValue, + end: model.maxValue, + steps: divisionInterval, ), ]; - if (gaugeOrientation == LinearGaugeOrientation.vertical) { + if (gaugeOrientation == GaugeOrientation.vertical) { return Row( mainAxisAlignment: MainAxisAlignment.center, children: children, diff --git a/pubspec.lock b/pubspec.lock index 35f7cf27..3d92364e 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -448,6 +448,15 @@ packages: url: "https://pub.dev" source: hosted version: "4.0.0" + geekyants_flutter_gauges: + dependency: "direct main" + description: + path: "." + ref: elastic-version + resolved-ref: "141b95f6dd606204d47134107c1ddc2bbe4879cb" + url: "https://github.com/Gold872/GaugesFlutter.git" + source: git + version: "1.0.4" github: dependency: "direct main" description: @@ -1005,14 +1014,6 @@ packages: url: "https://pub.dev" source: hosted version: "23.2.7" - syncfusion_flutter_gauges: - dependency: "direct main" - description: - name: syncfusion_flutter_gauges - sha256: a559712b476b05ad2506925b5031dbba3c9e7ce83f482191a8185a3de054e7e6 - url: "https://pub.dev" - source: hosted - version: "23.2.7" term_glyph: dependency: transitive description: diff --git a/pubspec.yaml b/pubspec.yaml index 6c2a2fdb..107e33f3 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -22,6 +22,10 @@ dependencies: flutter_context_menu: ^0.1.3 flutter_fancy_tree_view: ^1.1.1 flutter_launcher_icons: ^0.13.1 + geekyants_flutter_gauges: + git: + url: https://github.com/Gold872/GaugesFlutter.git + ref: elastic-version github: ^9.17.0 http: ^1.2.0 import_sorter: ^4.6.0 @@ -39,7 +43,6 @@ dependencies: searchable_listview: ^2.7.0 shared_preferences: ^2.1.2 syncfusion_flutter_charts: ^23.1.44 - syncfusion_flutter_gauges: ^23.1.44 titlebar_buttons: ^1.0.0 transitioned_indexed_stack: ^1.0.2 url_launcher: ^6.3.0 diff --git a/test/widgets/nt_widgets/multi-topic/differential_drive_test.dart b/test/widgets/nt_widgets/multi-topic/differential_drive_test.dart index 38d3e524..767a94b9 100644 --- a/test/widgets/nt_widgets/multi-topic/differential_drive_test.dart +++ b/test/widgets/nt_widgets/multi-topic/differential_drive_test.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/services/nt_connection.dart'; @@ -94,11 +94,11 @@ void main() { await widgetTester.pumpAndSettle(); expect(find.byType(CustomPaint), findsWidgets); - expect(find.byType(SfLinearGauge), findsNWidgets(2)); - expect(find.byType(LinearShapePointer), findsNWidgets(2)); + expect(find.byType(LinearGauge), findsNWidgets(2)); + expect(find.byType(Pointer), findsNWidgets(2)); await widgetTester.drag( - find.byType(LinearShapePointer).first, const Offset(0.0, 200.0)); + find.byType(Pointer).first, const Offset(0.0, 200.0)); await widgetTester.pumpAndSettle(); expect( @@ -111,7 +111,7 @@ void main() { 0.50); await widgetTester.drag( - find.byType(LinearShapePointer).last, const Offset(0.0, 300.0)); + find.byType(Pointer).last, const Offset(0.0, 300.0)); await widgetTester.pumpAndSettle(); expect( diff --git a/test/widgets/nt_widgets/multi-topic/gyro_test.dart b/test/widgets/nt_widgets/multi-topic/gyro_test.dart index e110daf5..676dd197 100644 --- a/test/widgets/nt_widgets/multi-topic/gyro_test.dart +++ b/test/widgets/nt_widgets/multi-topic/gyro_test.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/services/nt_connection.dart'; @@ -96,6 +96,6 @@ void main() { await widgetTester.pumpAndSettle(); expect(find.text('176.50'), findsOneWidget); - expect(find.byType(SfRadialGauge), findsOneWidget); + expect(find.byType(RadialGauge), findsOneWidget); }); } diff --git a/test/widgets/nt_widgets/multi-topic/motor_controller_test.dart b/test/widgets/nt_widgets/multi-topic/motor_controller_test.dart index 306d9b10..28200735 100644 --- a/test/widgets/nt_widgets/multi-topic/motor_controller_test.dart +++ b/test/widgets/nt_widgets/multi-topic/motor_controller_test.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/services/nt_connection.dart'; @@ -100,7 +100,7 @@ void main() { await widgetTester.pumpAndSettle(); expect(find.text('-0.50'), findsOneWidget); - expect(find.byType(SfLinearGauge), findsOneWidget); - expect(find.byType(LinearShapePointer), findsOneWidget); + expect(find.byType(LinearGauge), findsOneWidget); + expect(find.byType(Pointer), findsOneWidget); }); } diff --git a/test/widgets/nt_widgets/single-topic/number_bar_test.dart b/test/widgets/nt_widgets/single-topic/number_bar_test.dart index d45e58f3..2481df80 100644 --- a/test/widgets/nt_widgets/single-topic/number_bar_test.dart +++ b/test/widgets/nt_widgets/single-topic/number_bar_test.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/services/nt_connection.dart'; @@ -126,12 +126,12 @@ void main() { await widgetTester.pumpAndSettle(); expect(find.text('-1.00'), findsOneWidget); - expect(find.byType(SfLinearGauge), findsOneWidget); + expect(find.byType(LinearGauge), findsOneWidget); expect( - (find.byType(SfLinearGauge).evaluate().first.widget as SfLinearGauge) - .orientation, - LinearGaugeOrientation.horizontal); + (find.byType(LinearGauge).evaluate().first.widget as LinearGauge) + .gaugeOrientation, + GaugeOrientation.horizontal); }); testWidgets('Number bar widget test vertical', (widgetTester) async { @@ -164,12 +164,12 @@ void main() { await widgetTester.pumpAndSettle(); expect(find.text('-1.00'), findsOneWidget); - expect(find.byType(SfLinearGauge), findsOneWidget); + expect(find.byType(LinearGauge), findsOneWidget); expect( - (find.byType(SfLinearGauge).evaluate().first.widget as SfLinearGauge) - .orientation, - LinearGaugeOrientation.vertical); + (find.byType(LinearGauge).evaluate().first.widget as LinearGauge) + .gaugeOrientation, + GaugeOrientation.vertical); }); testWidgets('Number bar widget test integer', (widgetTester) async { @@ -216,7 +216,7 @@ void main() { expect(find.text('-1.00'), findsNothing); expect(find.text('-1'), findsOneWidget); - expect(find.byType(SfLinearGauge), findsOneWidget); + expect(find.byType(LinearGauge), findsOneWidget); }); testWidgets('Number bar widget test with divisions', (widgetTester) async { @@ -249,11 +249,10 @@ void main() { await widgetTester.pumpAndSettle(); expect(find.text('-1.00'), findsOneWidget); - expect(find.byType(SfLinearGauge), findsOneWidget); + expect(find.byType(LinearGauge), findsOneWidget); expect( - (find.byType(SfLinearGauge).evaluate().first.widget as SfLinearGauge) - .interval, + (find.byType(LinearGauge).evaluate().first.widget as LinearGauge).steps, 1.0); }); } diff --git a/test/widgets/nt_widgets/single-topic/number_slider_test.dart b/test/widgets/nt_widgets/single-topic/number_slider_test.dart index a178e937..c2cea09d 100644 --- a/test/widgets/nt_widgets/single-topic/number_slider_test.dart +++ b/test/widgets/nt_widgets/single-topic/number_slider_test.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/services/nt_connection.dart'; @@ -119,11 +119,11 @@ void main() { await widgetTester.pumpAndSettle(); expect(find.text('-1.00'), findsOneWidget); - expect(find.byType(SfLinearGauge), findsOneWidget); - expect(find.byType(LinearShapePointer), findsOneWidget); + expect(find.byType(LinearGauge), findsOneWidget); + expect(find.byType(Pointer), findsOneWidget); Future pointerDrag = widgetTester.timedDrag( - find.byType(LinearShapePointer), + find.byType(Pointer), const Offset(100.0, 0.0), const Duration(seconds: 1), ); @@ -177,11 +177,11 @@ void main() { await widgetTester.pumpAndSettle(); expect(find.text('-1.00'), findsOneWidget); - expect(find.byType(SfLinearGauge), findsOneWidget); - expect(find.byType(LinearShapePointer), findsOneWidget); + expect(find.byType(LinearGauge), findsOneWidget); + expect(find.byType(Pointer), findsOneWidget); Future pointerDrag = widgetTester.timedDrag( - find.byType(LinearShapePointer), + find.byType(Pointer), const Offset(100.0, 0.0), const Duration(seconds: 1), ); @@ -247,11 +247,11 @@ void main() { expect(find.text('-1.00'), findsNothing); expect(find.text('-1'), findsOneWidget); - expect(find.byType(SfLinearGauge), findsOneWidget); - expect(find.byType(LinearShapePointer), findsOneWidget); + expect(find.byType(LinearGauge), findsOneWidget); + expect(find.byType(Pointer), findsOneWidget); Future pointerDrag = widgetTester.timedDrag( - find.byType(LinearShapePointer), + find.byType(Pointer), const Offset(200.0, 0.0), const Duration(seconds: 1), ); diff --git a/test/widgets/nt_widgets/single-topic/radial_gauge_test.dart b/test/widgets/nt_widgets/single-topic/radial_gauge_test.dart index c30f5e6c..f9d3140d 100644 --- a/test/widgets/nt_widgets/single-topic/radial_gauge_test.dart +++ b/test/widgets/nt_widgets/single-topic/radial_gauge_test.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/services/nt_connection.dart'; @@ -166,7 +166,7 @@ void main() { home: Scaffold( body: ChangeNotifierProvider.value( value: radialGaugeModel, - child: const RadialGauge(), + child: const RadialGaugeWidget(), ), ), ), @@ -174,7 +174,7 @@ void main() { await widgetTester.pumpAndSettle(); - expect(find.byType(SfRadialGauge), findsOneWidget); + expect(find.byType(RadialGauge), findsOneWidget); expect(find.text('-0.50'), findsOneWidget); expect(find.byType(NeedlePointer), findsOneWidget); }); @@ -216,7 +216,7 @@ void main() { home: Scaffold( body: ChangeNotifierProvider.value( value: radialGaugeModel, - child: const RadialGauge(), + child: const RadialGaugeWidget(), ), ), ), @@ -224,7 +224,7 @@ void main() { await widgetTester.pumpAndSettle(); - expect(find.byType(SfRadialGauge), findsOneWidget); + expect(find.byType(RadialGauge), findsOneWidget); expect(find.text('-1.00'), findsNothing); expect(find.text('-1'), findsOneWidget); expect(find.byType(NeedlePointer), findsOneWidget); @@ -254,7 +254,7 @@ void main() { home: Scaffold( body: ChangeNotifierProvider.value( value: radialGaugeModel, - child: const RadialGauge(), + child: const RadialGaugeWidget(), ), ), ), @@ -262,7 +262,7 @@ void main() { await widgetTester.pumpAndSettle(); - expect(find.byType(SfRadialGauge), findsOneWidget); + expect(find.byType(RadialGauge), findsOneWidget); expect(find.text('-0.50'), findsOneWidget); expect(find.byType(NeedlePointer), findsNothing); }); diff --git a/test/widgets/nt_widgets/single-topic/voltage_view_test.dart b/test/widgets/nt_widgets/single-topic/voltage_view_test.dart index 4415df35..10350b47 100644 --- a/test/widgets/nt_widgets/single-topic/voltage_view_test.dart +++ b/test/widgets/nt_widgets/single-topic/voltage_view_test.dart @@ -1,9 +1,9 @@ import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; +import 'package:geekyants_flutter_gauges/geekyants_flutter_gauges.dart'; import 'package:provider/provider.dart'; import 'package:shared_preferences/shared_preferences.dart'; -import 'package:syncfusion_flutter_gauges/gauges.dart'; import 'package:elastic_dashboard/services/nt4_client.dart'; import 'package:elastic_dashboard/services/nt_connection.dart'; @@ -126,12 +126,12 @@ void main() { await widgetTester.pumpAndSettle(); expect(find.text('12.00 V'), findsOneWidget); - expect(find.byType(SfLinearGauge), findsOneWidget); + expect(find.byType(LinearGauge), findsOneWidget); expect( - (find.byType(SfLinearGauge).evaluate().first.widget as SfLinearGauge) - .orientation, - LinearGaugeOrientation.horizontal); + (find.byType(LinearGauge).evaluate().first.widget as LinearGauge) + .gaugeOrientation, + GaugeOrientation.horizontal); }); testWidgets('Voltage view widget test vertical', (widgetTester) async { @@ -164,12 +164,12 @@ void main() { await widgetTester.pumpAndSettle(); expect(find.text('12.00 V'), findsOneWidget); - expect(find.byType(SfLinearGauge), findsOneWidget); + expect(find.byType(LinearGauge), findsOneWidget); expect( - (find.byType(SfLinearGauge).evaluate().first.widget as SfLinearGauge) - .orientation, - LinearGaugeOrientation.vertical); + (find.byType(LinearGauge).evaluate().first.widget as LinearGauge) + .gaugeOrientation, + GaugeOrientation.vertical); }); testWidgets('Voltage view widget test with divisions', (widgetTester) async { @@ -202,11 +202,10 @@ void main() { await widgetTester.pumpAndSettle(); expect(find.text('12.00 V'), findsOneWidget); - expect(find.byType(SfLinearGauge), findsOneWidget); + expect(find.byType(LinearGauge), findsOneWidget); expect( - (find.byType(SfLinearGauge).evaluate().first.widget as SfLinearGauge) - .interval, + (find.byType(LinearGauge).evaluate().first.widget as LinearGauge).steps, 0.9); }); }