Articles in this section
Category / Section

How to add progressive (nonlinear) scale in Flutter radial gauge (SfRadialGauge)

3 mins read

Description

This article describes how to add the progressive axis scale such as 0, 2, 5,10,20,30,50,100, and 150 using the Flutter radial gauge widget.

Solution

You can show the progressive scale(nonlinear) using the radial gauge widget by extending a custom axis renderer from radial axis renderer class.

Step 1: Create a custom axis renderer class by extending it from radial axis renderer.

class _CustomAxisRenderer extends RadialAxisRenderer {
  _CustomAxisRenderer() : super();
}

 

Step 2: The text value of the labels can be changed as required visible labels by overriding the generateVisibleLabels method of custom axis renderer.

 /// Generated the 9 non-linear interval labels from 0 to 150
  /// instead of actual generated labels.
  @override
  List<CircularAxisLabel> generateVisibleLabels() {
    final List<CircularAxisLabel> _visibleLabels = <CircularAxisLabel>[];
    for (num i = 0; i < 9; i++) {
      final double _value = _calculateLabelValue(i);
      final CircularAxisLabel label = CircularAxisLabel(
          this.axis.axisLabelStyle, _value.toInt().toString(), i, false);
      label.value = _value;
      _visibleLabels.add(label);
    }
 
    return _visibleLabels;
  }
 
  /// To return the label value based on interval
  double _calculateLabelValue(num value) {
    if (value == 0) {
      return 0;
    } else if (value == 1) {
      return 2;
    } else if (value == 2) {
      return 5;
    } else if (value == 3) {
      return 10;
    } else if (value == 4) {
      return 20;
    } else if (value == 5) {
      return 30;
    } else if (value == 6) {
      return 50;
    } else if (value == 7) {
      return 100;
    } else {
      return 150;
    }
  }

 

 

Step 3: The visible label values are converted to a factor values (from 0 to 1) on the axis range by overriding the valueToFactor method of the custom axis renderer class.

@override
  double valueToFactor(double value) {
    if (value >= 0 && value <= 2) {
      return (value * 0.125) / 2;
    } else if (value > 2 && value <= 5) {
      return (((value - 2) * 0.125) / (5 - 2)) + (1 * 0.125);
    } else if (value > 5 && value <= 10) {
      return (((value - 5) * 0.125) / (10 - 5)) + (2 * 0.125);
    } else if (value > 10 && value <= 20) {
      return (((value - 10) * 0.125) / (20 - 10)) + (3 * 0.125);
    } else if (value > 20 && value <= 30) {
      return (((value - 20) * 0.125) / (30 - 20)) + (4 * 0.125);
    } else if (value > 30 && value <= 50) {
      return (((value - 30) * 0.125) / (50 - 30)) + (5 * 0.125);
    } else if (value > 50 && value <= 100) {
      return (((value - 50) * 0.125) / (100 - 50)) + (6 * 0.125);
    } else if (value > 100 && value <= 150) {
      return (((value - 100) * 0.125) / (150 - 100)) + (7 * 0.125);
    } else {
      return 1;
    }
  }

 

Step 4: Create the radial gauge and add the radial axis by customizing the axis range as desired.

@override
Widget build(BuildContext context) {
  return Scaffold(
    backgroundColor: Colors.white,
    body: Center(
      child: SfRadialGauge(
        axes: <RadialAxis>[
          RadialAxis(
            minimum: 0,
            maximum: 150,
          )
        ],
      ),
    ),
  );
}

 

Step 5: Return the custom axis renderer in the onCreateAxisRenderer event of radial axis.

 axes: <RadialAxis>[
          RadialAxis(
            minimum: 0,
            maximum: 150,
            onCreateAxisRenderer: () {
              final CustomAxisRenderer renderer = CustomAxisRenderer();
              return renderer;
            },
          )
        ]
 

 

Step 6: Include the range pointer and needle pointer to annotate the desired value.

axes: <RadialAxis>[
            RadialAxis(minimum: 0, maximum: 150, 
              onCreateAxisRenderer: () {
                  final CustomAxisRenderer renderer = CustomAxisRenderer();
                  return renderer;
                },  pointers: <GaugePointer>[
                 NeedlePointer(
                  gradient: LinearGradient(colors: const <Color>[
                    Color.fromRGBO(203, 126, 223, 0.1),
                    Color(0xFFCB7EDF)
                  ], stops: const <double>[
                    0.25,
                    0.75
                  ], begin: Alignment.bottomCenter, end: Alignment.topCenter),
                  value: 60),
              RangePointer(
                value: 60,
                gradient: const SweepGradient(
                    colors: <Color>[Color(0xFF9E40DC), Color(0xFFE63B86)],
                    stops: <double>[0.25, 0.75]),
              )
            ])
          ],

 

Output

 

progressive scale

 

 

 

 

 

 

 

 

 

You can download the demo sample from this link.

 

Did you find this information helpful?
Yes
No
Help us improve this page
Please provide feedback or comments
Comments (0)
Please sign in to leave a comment
Access denied
Access denied