diff --git a/lib/src/linear_gauge/pointers/linear_gauge_shape_pointer.dart b/lib/src/linear_gauge/pointers/linear_gauge_shape_pointer.dart index bca7cddf..6d3d532f 100644 --- a/lib/src/linear_gauge/pointers/linear_gauge_shape_pointer.dart +++ b/lib/src/linear_gauge/pointers/linear_gauge_shape_pointer.dart @@ -40,6 +40,7 @@ class Pointer extends LeafRenderObjectWidget implements BasePointer { this.animationDuration = 1000, this.animationType = Curves.ease, this.enableAnimation = true, + this.labelFormatter, }) : super(key: key); /// @@ -141,6 +142,19 @@ class Pointer extends LeafRenderObjectWidget implements BasePointer { /// final bool showLabel; + /// + /// `labelFormatter` formats a custom label for the pointer on the [Pointer] + /// + /// E.g., Value with % + /// ```dart + /// const LinearGauge( + /// pointer: Pointer( + /// labelFormatter: (double? value) => '$value%', + /// ), + /// ), + /// ``` + final String Function(double? value)? labelFormatter; + /// /// `quarterTurns` Sets the rotation of the label of `pointer` /// @@ -250,23 +264,25 @@ class Pointer extends LeafRenderObjectWidget implements BasePointer { RenderObject createRenderObject(BuildContext context) { final LinearGaugeState linearGaugeScope = LinearGaugeState.of(context); return RenderLinearGaugeShapePointer( - value: value, - color: color, - width: width, - isInteractive: isInteractive, - height: height, - pointerPosition: pointerPosition, - shape: shape, - pointerAlignment: pointerAlignment, - animationDuration: animationDuration, - showLabel: showLabel, - animationType: animationType, - quarterTurns: quarterTurns, - enableAnimation: enableAnimation, - labelStyle: labelStyle, - onChanged: onChanged, - pointerAnimation: linearGaugeScope.animation!, - linearGauge: linearGaugeScope.lGauge); + value: value, + color: color, + width: width, + isInteractive: isInteractive, + height: height, + pointerPosition: pointerPosition, + shape: shape, + pointerAlignment: pointerAlignment, + animationDuration: animationDuration, + showLabel: showLabel, + animationType: animationType, + quarterTurns: quarterTurns, + enableAnimation: enableAnimation, + labelStyle: labelStyle, + onChanged: onChanged, + pointerAnimation: linearGaugeScope.animation!, + linearGauge: linearGaugeScope.lGauge, + labelFormatter: labelFormatter, + ); } @override @@ -289,7 +305,8 @@ class Pointer extends LeafRenderObjectWidget implements BasePointer { ..setLinearGAuge = linearGaugeScope.lGauge ..onChanged = onChanged ..setIsInteractive = isInteractive - ..setLabelStyle = labelStyle; + ..setLabelStyle = labelStyle + ..setLabelFormatter = labelFormatter; super.updateRenderObject(context, renderObject); } diff --git a/lib/src/linear_gauge/pointers/linear_gauge_shape_pointer_painter.dart b/lib/src/linear_gauge/pointers/linear_gauge_shape_pointer_painter.dart index c7e23886..157b7e90 100644 --- a/lib/src/linear_gauge/pointers/linear_gauge_shape_pointer_painter.dart +++ b/lib/src/linear_gauge/pointers/linear_gauge_shape_pointer_painter.dart @@ -27,6 +27,7 @@ class RenderLinearGaugeShapePointer extends RenderOpacity { required bool isInteractive, required Animation pointerAnimation, required LinearGauge linearGauge, + required String Function(double? value)? labelFormatter, }) : _value = value, _height = height, _onChanged = onChanged, @@ -41,7 +42,8 @@ class RenderLinearGaugeShapePointer extends RenderOpacity { _linearGauge = linearGauge, _pointerAnimation = pointerAnimation, _isInteractive = isInteractive, - _enableAnimation = enableAnimation; + _enableAnimation = enableAnimation, + _labelFormatter = labelFormatter; double yAxisForGaugeContainer = 0, xAxisForGaugeContainer = 0; late LinearGaugeLabel linearGaugeLabel; @@ -177,6 +179,20 @@ class RenderLinearGaugeShapePointer extends RenderOpacity { markNeedsPaint(); } + /// Gets the labelFormatter assigned to [RenderLinearGaugeShapePointer]. + String Function(double? value)? get labelFormatter => _labelFormatter; + String Function(double? value)? _labelFormatter; + + /// Sets the labelFormatter for [RenderLinearGaugeShapePointer]. + set setLabelFormatter(String Function(double? value)? value) { + if (value == _labelFormatter) { + return; + } + + _labelFormatter = value; + markNeedsPaint(); + } + /// Gets the quarterTurns assigned to [RenderLinearGaugeShapePointer]. QuarterTurns get quarterTurns => _quarterTurns; QuarterTurns _quarterTurns; @@ -341,7 +357,7 @@ class RenderLinearGaugeShapePointer extends RenderOpacity { return; } - if (showLabel) { + if (showLabel || labelFormatter != null) { _drawLabel(canvas, offset, quarterTurns, rulerPosition, linearGauge); } } @@ -356,11 +372,14 @@ class RenderLinearGaugeShapePointer extends RenderOpacity { textAlign: TextAlign.center, ); - textPainter.text = TextSpan( - text: value == null ? linearGauge.value!.toString() : value.toString(), - style: labelStyle); - offset = applyAnimations(linearGauge, offset); + // Attempt to get the custom label value, + // if null fallback on the standard value. + final String pointerText = value != null + ? (labelFormatter?.call(value) ?? value.toString()) + : linearGauge.value!.toString(); + textPainter.text = TextSpan(text: pointerText, style: labelStyle); + offset = applyAnimations(linearGauge, offset); textPainter.layout(); if (shape == PointerShape.circle) { if (gaugeOrientation == GaugeOrientation.horizontal) { diff --git a/lib/src/radial_gauge/pointer/radial_shape_pointer.dart b/lib/src/radial_gauge/pointer/radial_shape_pointer.dart index 75bc510b..bbeaab6a 100644 --- a/lib/src/radial_gauge/pointer/radial_shape_pointer.dart +++ b/lib/src/radial_gauge/pointer/radial_shape_pointer.dart @@ -37,6 +37,8 @@ class RadialShapePointer extends LeafRenderObjectWidget { this.onChanged, this.isInteractive = false, this.shape = PointerShape.triangle, + this.borderColor, + this.borderWidth, }); /// @@ -83,6 +85,18 @@ class RadialShapePointer extends LeafRenderObjectWidget { /// final PointerShape shape; + /// + /// `borderColor` draws a border around the [RadialShapePointer] on the [RadialGauge] + /// If null, no border is drawn + /// + final Color? borderColor; + + /// + /// `borderWidth` draws a border around the [RadialShapePointer] on the [RadialGauge] + /// If null, no border is drawn + /// + final double? borderWidth; + @override RenderObject createRenderObject(BuildContext context) { final RadialGaugeState scope = RadialGaugeState.of(context); @@ -96,6 +110,8 @@ class RadialShapePointer extends LeafRenderObjectWidget { onChanged: onChanged, shape: shape, radialGauge: scope.rGauge, + borderColor: borderColor, + borderWidth: borderWidth, ); } @@ -111,6 +127,8 @@ class RadialShapePointer extends LeafRenderObjectWidget { ..setWidth = width ..onChanged = onChanged ..setIsInteractive = isInteractive - ..setShape = shape; + ..setShape = shape + ..setBorderColor = borderColor + ..setBorderWidth = borderWidth; } } diff --git a/lib/src/radial_gauge/pointer/radial_shape_pointer_painter.dart b/lib/src/radial_gauge/pointer/radial_shape_pointer_painter.dart index e35bb024..03f7e51b 100644 --- a/lib/src/radial_gauge/pointer/radial_shape_pointer_painter.dart +++ b/lib/src/radial_gauge/pointer/radial_shape_pointer_painter.dart @@ -14,6 +14,8 @@ class RenderRadialShapePointer extends RenderBox { required bool isInteractive, required PointerShape shape, required RadialGauge radialGauge, + required Color? borderColor, + required double? borderWidth, }) : _value = value, _color = color, _height = height, @@ -21,7 +23,9 @@ class RenderRadialShapePointer extends RenderBox { _isInteractive = isInteractive, _width = width, _shape = shape, - _radialGauge = radialGauge; + _radialGauge = radialGauge, + _borderColor = borderColor, + _borderWidth = borderWidth; double _value; Color _color; @@ -29,6 +33,8 @@ class RenderRadialShapePointer extends RenderBox { double _width; PointerShape _shape; RadialGauge _radialGauge; + Color? _borderColor; + double? _borderWidth; @override Size computeDryLayout(BoxConstraints constraints) { @@ -124,6 +130,22 @@ class RenderRadialShapePointer extends RenderBox { markNeedsPaint(); } + set setBorderColor(Color? borderColor) { + if (_borderColor == borderColor) { + return; + } + _borderColor = borderColor; + markNeedsPaint(); + } + + set setBorderWidth(double? borderWidth) { + if (_borderWidth == borderWidth) { + return; + } + _borderWidth = borderWidth; + markNeedsPaint(); + } + late Rect pointerRect; @override @@ -182,6 +204,16 @@ class RenderRadialShapePointer extends RenderBox { center: Offset(pointerEndX, pointerEndY), radius: _width); // canvas.drawRect(pointerRect, Paint()..color = _color); + if (_borderColor != null && _borderWidth != null) { + canvas.drawCircle( + Offset(circlePointerEndX, circlePointerEndY), + _width + (_borderWidth! / 2), + Paint() + ..color = _borderColor! + ..style = PaintingStyle.stroke + ..strokeWidth = _borderWidth!, + ); + } canvas.drawCircle(Offset(circlePointerEndX, circlePointerEndY), _width, Paint()..color = _color); // canvas.drawPath(pointerPath, Paint()..color = _color);