Marker pointer in Flutter Radial Gauge (SfRadialGauge)

20 Jul 202624 minutes to read

A MarkerPointer is used to indicate a specific value on the radial gauge axis. It supports seven built-in marker shapes and additional customization options such as image, text, color, size, border, elevation, overlay, and position offset. The marker type can be changed using the markerType property. The default marker type is MarkerType.invertedTriangle.

The following example demonstrates adding a default marker pointer to the radial gauge.

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: MarkerPointerExample(),
        );
      }
    }
    
    class MarkerPointerExample extends StatelessWidget {
      const MarkerPointerExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(value: 60)
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    default marker pointer

    Marker types

    The radial gauge supports the following built-in marker types that can be set using the markerType property of MarkerPointer:

    Circle

    The MarkerType.circle renders the marker pointer as a filled circle. This is one of the default built-in shapes available out of the box.

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: CircleMarkerExample(),
        );
      }
    }
    
    class CircleMarkerExample extends StatelessWidget {
      const CircleMarkerExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 60,
                      markerType: MarkerType.circle,
                      markerHeight: 20,
                      markerWidth: 20,
                      color: Colors.lightBlue,
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    circle marker pointer

    Diamond

    The MarkerType.diamond renders the marker pointer as a diamond shape. It is useful for highlighting specific values on a gradient scale where a square or rotated rectangle better matches the visual style.

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: DiamondMarkerExample(),
        );
      }
    }
    
    class DiamondMarkerExample extends StatelessWidget {
      const DiamondMarkerExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 70,
                      markerType: MarkerType.diamond,
                      markerHeight: 20,
                      markerWidth: 20,
                      color: Colors.lightBlue,
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    diamond marker pointer

    Inverted triangle

    The MarkerType.invertedTriangle renders the marker pointer as a downward-pointing triangle. This is the default marker shape when no markerType is specified.

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: InvertedTriangleMarkerExample(),
        );
      }
    }
    
    class InvertedTriangleMarkerExample extends StatelessWidget {
      const InvertedTriangleMarkerExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 50,
                      markerType: MarkerType.invertedTriangle,
                      markerHeight: 20,
                      markerWidth: 20,
                      color: Colors.lightBlue,
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    inverted triangle marker pointer

    Rectangle

    The MarkerType.rectangle renders the marker pointer as a rectangle. It is useful for filling longer ranges on the axis where a circular or triangular marker would not provide sufficient visual weight.

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: RectangleMarkerExample(),
        );
      }
    }
    
    class RectangleMarkerExample extends StatelessWidget {
      const RectangleMarkerExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 40,
                      markerType: MarkerType.rectangle,
                      markerHeight: 20,
                      markerWidth: 20,
                      color: Colors.lightBlue,
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    rectangle marker pointer

    Triangle

    The MarkerType.triangle renders the marker pointer as an upward-pointing triangle. It is commonly used as a directional indicator on the gauge.

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: TriangleMarkerExample(),
        );
      }
    }
    
    class TriangleMarkerExample extends StatelessWidget {
      const TriangleMarkerExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 80,
                      markerType: MarkerType.triangle,
                      markerHeight: 20,
                      markerWidth: 20,
                      color: Colors.lightBlue,
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    triangle marker pointer

    Image pointer

    An image can be used to denote the current pointer values instead of a shape. This can be achieved by setting the markerType as image and specifying the imageUrl property of the marker pointer.

    NOTE

    Add the image to your pubspec.yaml file under the flutter > assets section so that it is available to the application.

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: ImageMarkerExample(),
        );
      }
    }
    
    class ImageMarkerExample extends StatelessWidget {
      const ImageMarkerExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 60,
                      markerType: MarkerType.image,
                      markerHeight: 30,
                      markerWidth: 30,
                      imageUrl: 'images/pin.png'
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    image pointer

    Text pointer

    Text can be used to denote the current pointer value instead of any marker shape. This can be achieved by setting the markerType as text. The provided text can be customized using the textStyle property of the marker pointer, which accepts a GaugeTextStyle for gauge-specific text formatting.

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: TextMarkerExample(),
        );
      }
    }
    
    class TextMarkerExample extends StatelessWidget {
      const TextMarkerExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 50,
                      markerType: MarkerType.text,
                      text: 'Average',
                      textStyle: GaugeTextStyle(
                        fontSize: 15,
                        fontWeight: FontWeight.bold,
                        fontStyle: FontStyle.italic
                      )
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    text pointer

    Marker customization

    The marker pointer can be customized using the following properties:

    • color – Allows you to customize the marker color.
    • markerHeight – Allows you to specify the marker height.
    • markerWidth – Allows you to specify the marker width.
    • borderColor – Allows you to specify the border color for the marker.
    • borderWidth – Allows you to specify the border width of the marker.
  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: MarkerCustomizationExample(),
        );
      }
    }
    
    class MarkerCustomizationExample extends StatelessWidget {
      const MarkerCustomizationExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 60,
                      markerHeight: 30,
                      markerWidth: 30,
                      markerType: MarkerType.circle,
                      color: Colors.lightBlue,
                      borderWidth: 3,
                      borderColor: Colors.black
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    marker pointer customization

    Marker elevation

    The marker pointer can be elevated by rendering its shadow behind it. The z- coordinate position at which the shadow can be positioned relative to the marker can be controlled by the elevation property.

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: MarkerElevationExample(),
        );
      }
    }
    
    class MarkerElevationExample extends StatelessWidget {
      const MarkerElevationExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 60,
                      markerHeight: 20,
                      markerWidth: 20,
                      elevation: 4
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    marker elevation

    The shadow color of the pointer is black by default and the default value of elevation is 0.

    NOTE

    The elevation property applies to all the marker types except MarkerType.image and MarkerType.text.

    Marker overlay

    The marker overlay is rendered around the marker when the marker is dragged. When enableDragging property of the marker is set to true and while dragging the marker, the overlay will appear around the marker pointer.

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: MarkerOverlayExample(),
        );
      }
    }
    
    class MarkerOverlayExample extends StatelessWidget {
      const MarkerOverlayExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 60,
                      markerHeight: 20,
                      markerWidth: 20,
                      enableDragging: true,
                      markerType: MarkerType.circle
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    marker overlay

    By default, the overlayRadius is calculated based on the provided markerHeight and markerWidth property and the overlayColor is derived from the marker color. The following properties are used to customize the overlay color and its radius,

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: MarkerOverlayCustomizationExample(),
        );
      }
    }
    
    class MarkerOverlayCustomizationExample extends StatelessWidget {
      const MarkerOverlayCustomizationExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 60,
                      markerHeight: 20,
                      markerWidth: 20,
                      enableDragging: true,
                      overlayRadius: 15,
                      overlayColor: Colors.red.withValues(alpha: 0.12),
                      markerType: MarkerType.circle
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    overlay customization

    NOTE

    The marker overlay applies to all the marker types except MarkerType.image and MarkerType.text.

    Pointer interaction

    The marker pointer supports interactive value changes by enabling the enableDragging property. When this property is set to true, the user can drag the marker pointer along the axis to update its value. The following callbacks are invoked during the drag interaction:

    • onValueChanged – Called continuously while the user is dragging the marker pointer and selecting a new value.
    • onValueChangeStart – Called when the user starts dragging the marker pointer.
    • onValueChangeEnd – Called when the user finishes dragging the marker pointer.
    • onValueChanging – Called before the value is updated during the drag, providing a ValueChangingArgs instance for advanced scenarios such as restricting the value range.
  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: MarkerInteractionExample(),
        );
      }
    }
    
    class MarkerInteractionExample extends StatefulWidget {
      const MarkerInteractionExample({Key? key}) : super(key: key);
    
      @override
      State<MarkerInteractionExample> createState() => _MarkerInteractionExampleState();
    }
    
    class _MarkerInteractionExampleState extends State<MarkerInteractionExample> {
      double _markerValue = 60;
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: _markerValue,
                      enableDragging: true,
                      markerHeight: 20,
                      markerWidth: 20,
                      markerType: MarkerType.circle,
                      onValueChanged: (double newValue) {
                        setState(() {
                          _markerValue = newValue;
                        });
                      },
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    Custom renderer

    For advanced scenarios that require fully custom drawing, the marker pointer exposes the onCreatePointerRenderer callback. This callback receives a MarkerPointerRendererFactory and lets you return a custom MarkerPointerRenderer for complete control over how the marker is drawn.

    NOTE

    The onCreatePointerRenderer callback applies only when you need a custom rendering pipeline. It is not applicable for the built-in marker types described above.

    Position customization

    The marker pointer can be moved near or far from its actual position using the markerOffset and offsetUnit properties.

    When you set offsetUnit to logical pixel, the marker pointer will be moved based on the logical pixel value. If you set offsetUnit to factor, then provided factor will be multiplied with the axis radius value, and the pointer will be moved to the corresponding position. The default value of offsetUnit is GaugeSizeUnit.logicalPixel.

  • DART
  • import 'package:flutter/material.dart';
    import 'package:syncfusion_flutter_gauges/gauges.dart';
    
    void main() {
      runApp(const MyApp());
    }
    
    class MyApp extends StatelessWidget {
      const MyApp({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return const MaterialApp(
          home: MarkerOffsetExample(),
        );
      }
    }
    
    class MarkerOffsetExample extends StatelessWidget {
      const MarkerOffsetExample({Key? key}) : super(key: key);
    
      @override
      Widget build(BuildContext context) {
        return Scaffold(
          body: Center(
            child: SfRadialGauge(
              axes: <RadialAxis>[
                RadialAxis(
                  radiusFactor: 0.9,
                  centerY: 0.65,
                  pointers: <GaugePointer>[
                    MarkerPointer(
                      value: 60,
                      markerOffset: -5
                    )
                  ]
                )
              ],
            )
          ),
        );
      }
    }

    marker offset