LCOV - code coverage report
Current view: top level - lib/charts/painter - gauge_painter.dart (source / functions) Hit Total Coverage
Test: lcov.info Lines: 0 65 0.0 %
Date: 2024-10-04 11:12:13 Functions: 0 0 -

          Line data    Source code
       1             : // Copyright 2023 The terCAD team. All rights reserved.
       2             : // Use of this source code is governed by a CC BY-NC-ND 4.0 license that can be found in the LICENSE file.
       3             : 
       4             : import 'package:app_finance/_classes/herald/app_locale.dart';
       5             : import 'package:flutter/material.dart';
       6             : import 'package:intl/intl.dart' as intl;
       7             : import 'dart:math';
       8             : 
       9             : typedef FnShift = double Function(double dx, TextPainter textPainter);
      10             : 
      11             : class GaugePainter extends CustomPainter {
      12             :   final double value;
      13             :   final double max;
      14             :   final double min;
      15             :   final Color color;
      16             :   late final intl.NumberFormat formatter;
      17             :   final double threshold = 80;
      18             :   final double fontSize;
      19             : 
      20           0 :   GaugePainter({
      21             :     required this.value,
      22             :     required this.max,
      23             :     required this.min,
      24             :     this.color = Colors.grey,
      25             :     this.fontSize = 12,
      26             :   }) {
      27           0 :     formatter = intl.NumberFormat.compact(locale: AppLocale.code);
      28             :   }
      29             : 
      30           0 :   @override
      31             :   void paint(Canvas canvas, Size size) {
      32           0 :     final center = Offset(size.width / 2, size.height);
      33           0 :     final radius = size.width / 2;
      34             : 
      35           0 :     _drawArc(canvas, size, radius, center);
      36           0 :     if (size.width > threshold) {
      37           0 :       for (double i = 0.15; i < 1; i += 0.33) {
      38           0 :         _drawValue(canvas, size, radius, center, i);
      39             :       }
      40             :     }
      41           0 :     _drawLine(canvas, size, radius, center);
      42             :   }
      43             : 
      44           0 :   void _paintText(Canvas canvas, Size size, Offset position, String text) {
      45           0 :     callback(double dx, TextPainter textPainter) {
      46           0 :       double shift = cos(pi * position.dx / size.width);
      47           0 :       if (shift.toStringAsFixed(2) == '0.00') {
      48           0 :         shift = -textPainter.width / 2;
      49           0 :       } else if (position.dx >= size.width / 2) {
      50           0 :         shift = shift * textPainter.width * 1.5;
      51             :       } else {
      52           0 :         shift *= textPainter.width / 2;
      53             :       }
      54             :       return shift;
      55             :     }
      56             : 
      57           0 :     paintText(canvas, size, callback, position, text);
      58             :   }
      59             : 
      60           0 :   void paintText(Canvas canvas, Size size, FnShift shift, Offset position, String text) {
      61           0 :     final textPainter = TextPainter(
      62           0 :       text: TextSpan(
      63             :         text: text,
      64           0 :         style: TextStyle(
      65           0 :           color: color.withOpacity(0.8),
      66           0 :           fontSize: size.width > threshold * 2 ? fontSize : 9,
      67             :         ),
      68             :       ),
      69             :       textDirection: TextDirection.ltr,
      70             :     );
      71           0 :     textPainter.layout();
      72           0 :     textPainter.paint(canvas, Offset(position.dx + shift(position.dx, textPainter), position.dy));
      73             :   }
      74             : 
      75           0 :   void _drawValue(Canvas canvas, Size size, double radius, Offset center, double pos) {
      76           0 :     final line = Paint()
      77           0 :       ..color = color.withOpacity(0.5)
      78           0 :       ..strokeWidth = 1
      79           0 :       ..style = PaintingStyle.fill;
      80           0 :     final position = _getTip(radius, center, pos, 15);
      81           0 :     canvas.drawCircle(position, 1.5, line);
      82           0 :     _paintText(canvas, size, position, formatter.format(min + max * pos));
      83             :   }
      84             : 
      85           0 :   void _drawArc(Canvas canvas, Size size, double radius, Offset center) {
      86           0 :     final paint = Paint()
      87           0 :       ..color = Colors.green.shade500
      88           0 :       ..strokeWidth = 10
      89           0 :       ..style = PaintingStyle.stroke;
      90             : 
      91           0 :     double startPoint = (1 / 2.4 - 1) * pi;
      92           0 :     canvas.drawArc(Rect.fromCircle(center: center, radius: radius), startPoint, -startPoint, false, paint);
      93           0 :     canvas.drawArc(Rect.fromCircle(center: center, radius: radius), startPoint - pi / 3.8, pi / 4, false,
      94           0 :         paint..color = Colors.orange);
      95           0 :     canvas.drawArc(
      96           0 :         Rect.fromCircle(center: center, radius: radius), -pi, pi / 7.1, false, paint..color = Colors.red.shade900);
      97             :   }
      98             : 
      99           0 :   Offset _getTip(double radius, Offset center, double pos, [double needle = 20]) {
     100           0 :     final needleLength = radius - needle;
     101           0 :     final needleAngle = pi + pi * pos;
     102           0 :     return center.translate(needleLength * cos(needleAngle), needleLength * sin(needleAngle));
     103             :   }
     104             : 
     105           0 :   void _drawLine(Canvas canvas, Size size, double radius, Offset center) {
     106           0 :     final needleTip = _getTip(radius, center, value, size.width > threshold ? 20 : 0);
     107           0 :     final line = Paint()
     108           0 :       ..color = color
     109           0 :       ..strokeWidth = 2
     110           0 :       ..style = PaintingStyle.fill;
     111           0 :     final rnd = size.width > threshold ? 6.0 : 3.0;
     112           0 :     final shift = rnd / 2 * (needleTip.dx > radius ? 1 : -1);
     113           0 :     final path = Path()
     114           0 :       ..moveTo(radius - shift, size.height - rnd)
     115           0 :       ..lineTo(needleTip.dx, needleTip.dy)
     116           0 :       ..lineTo(radius + shift, size.height + rnd);
     117           0 :     canvas.drawPath(path, line);
     118           0 :     canvas.drawCircle(center, rnd, line);
     119             :   }
     120             : 
     121           0 :   @override
     122             :   bool shouldRepaint(CustomPainter oldDelegate) {
     123             :     return false;
     124             :   }
     125             : }

Generated by: LCOV version 1.14