From b7e7e87fe1e3d7d0eb001ee8cc47dbe0efcceee9 Mon Sep 17 00:00:00 2001 From: Mike S <69246756+mike-500@users.noreply.github.com> Date: Tue, 10 Dec 2024 19:01:46 +0000 Subject: [PATCH 1/2] Add support for a border around the circular radial shape pointer --- .../pointer/radial_shape_pointer.dart | 20 ++++++++++- .../pointer/radial_shape_pointer_painter.dart | 34 ++++++++++++++++++- 2 files changed, 52 insertions(+), 2 deletions(-) diff --git a/lib/src/radial_gauge/pointer/radial_shape_pointer.dart b/lib/src/radial_gauge/pointer/radial_shape_pointer.dart index 75bc510..bbeaab6 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 e35bb02..03f7e51 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); From 25447ae1c5709e00db4b6c0aec18c7984943dc34 Mon Sep 17 00:00:00 2001 From: Mike S <69246756+mike-500@users.noreply.github.com> Date: Thu, 12 Dec 2024 06:45:24 +0000 Subject: [PATCH 2/2] Added custom label formatter --- .../pointers/linear_gauge_shape_pointer.dart | 53 ++++++++++++------- .../linear_gauge_shape_pointer_painter.dart | 31 ++++++++--- 2 files changed, 60 insertions(+), 24 deletions(-) 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 bca7cdd..6d3d532 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 c7e2388..157b7e9 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) {