Search code examples
flutterdartsyncfusion

syncfusion_flutter_gauges value change not updating pointer


Using Gauge graph to show live data changes, but the pointer is not updating with the value change and it shows only the first value.

analytics.dart

import 'package:my_app/widgets/charts/gauge.dart';

// class _AnalyticsPageState extends State<AnalyticsPage> {
@override
  void initState() {
    super.initState();
    _timer = Timer.periodic(const Duration(seconds: 1), (timer) {
      _liveCurrent = randomNumber(dValue: true);
      _liveVoltage = randomNumber();
    });
  }

// usage
return Gauge(
  title: 'Voltage',
  pointer: _liveVoltage,
  minValue: 0,
  maxValue: 150,
  scales: [
    GaugeRange(
      startValue: 0,
      endValue: 50,
      color: Colors.green,
    ),
    GaugeRange(
      startValue: 50,
      endValue: 100,
      color: Colors.orange,
    ),
    GaugeRange(
      startValue: 100,
      endValue: 150,
      color: Colors.red,
    )
  ],
),

and the chart is defined in my_app/widgets/charts/gauge.dart

class Gauge extends StatefulWidget {

  final String? title;
  final List<GaugeRange> scales;
  final double pointer;
  final double minValue;
  final double maxValue;

  const Gauge({
    Key? key,
    this.title,
    required this.scales,
    this.pointer = 0,
    this.minValue = 0,
    this.maxValue = 100
  }) : super(key: key);

  @override
  State<Gauge> createState() => _GaugeState();
}

class _GaugeState extends State<Gauge> {

  Widget _getRadialGauge() {
    return SfRadialGauge(
        title: GaugeTitle(
            text: widget.title!,
            textStyle: const TextStyle(
                fontSize: 20.0,
                fontWeight: FontWeight.bold
            )
        ),
        axes: <RadialAxis>[
          RadialAxis(
              minimum: widget.minValue,
              maximum: widget.maxValue,
              ranges: widget.scales,
              pointers: <GaugePointer>[
                NeedlePointer(
                    value: widget.pointer
                )
              ],
              annotations: <GaugeAnnotation>[
                GaugeAnnotation(
                    widget: Text(
                        widget.pointer.toStringAsFixed(2),
                        style: const TextStyle(
                            fontSize: 25,
                            fontWeight: FontWeight.bold
                        )
                    ),
                    angle: 90,
                    positionFactor: 0.5
                )
              ]
          )
        ]
    );
  }

  @override
  Widget build(BuildContext context) {
    return _getRadialGauge();
  }
}

I want to make widget.pointer value dynamic and change the pointer when the value is changed in the parent widget Analytics.


Solution

  • Use setState when you update a value that should trigger the rebuilding of a stateful widget:

    setState(() {
      _liveVoltage = randomNumber();
    });
    
    

    I also recommend not the use Widget _getRadialGauge function but return the gauge from the build method:

    @override
    Widget build(BuildContext context) {
      return SfRadialGauge(...);
    }