How To Make A Curved Chart with Custom Painter Which Include Custom Tool-tip with Moving Cursor?

117 views Asked by At

enter image description here

I'm Learning Custom Paint and I'm Confused About Them i referred Few Documentation but Still i'm Lacking on it.

Referrence:Curved Chart, Paths

Some of the Code I have Mentioned Here ..Pls Help Me out of This....

import 'package:flutter/material.dart';
import 'dart:ui' as ui;

class ChartPainter extends CustomPainter {
  final List<String> x;
  final List<double> y;
  final double min, max;

  ChartPainter(this.x, this.y, this.min, this.max);

  final yLabelStyle = const TextStyle(color: Colors.white, fontSize: 14);
  final xLabelStyle = const TextStyle(
      color: Colors.white, fontSize: 16, fontWeight: FontWeight.bold);
  static double border = 10.0;
  static double radius = 5.0;
  final dotPaintFill = Paint()
    ..color = Colors.black
    ..style = PaintingStyle.fill
    ..strokeWidth = 2;
  final linePaint = Paint()
    ..color = Colors.white
    ..style = PaintingStyle.stroke
    ..strokeWidth = 2.0;
  @override
  void paint(Canvas canvas, Size size) {
    final clipRect = Rect.fromLTWH(0, 0, size.width, size.height);
    canvas.clipRect(clipRect);
    canvas.drawPaint(Paint()..color = Colors.black);

    final drawableHeight = size.height / 10.0 * border;
    final drawableWidth = size.width / 15 * border;
    final leftPadding = size.width / 6;
    final rightPadding = size.width / 1000;
    final hd = drawableHeight / 5.0;
    final wd = drawableWidth / x.length.toDouble();
    final height = hd * 3.0;
    final width = drawableWidth;
    if (height <= 0.0 || width <= 0.00) return;
    if (max - min < 1.0e-6) return;
    final hr = height / (max - min);
    final left = border;
    final top = border;
    final c = Offset(left + wd / 2.0, top + height / 2.0);

 
    _drawOutline(canvas, c, wd, height);
    final points = _computePoints(c, wd, height, hr);

    final fillpath = _computePath(
        points, drawableHeight, width, true, leftPadding, rightPadding);
    final labels = _computeLabels();


    canvas.drawPath(fillpath, linePaint);

    // drawvertical(canvas, c, wd, height, hr, wd);
    _drawDataPoints(canvas, points, dotPaintFill, linePaint);
    _drawYLabels(canvas, labels, points, wd, top);
    // final c1 = Offset(c.dx, top + 4 * hd);
    // _drawXLabels(canvas, c1, wd);
  }

  void _drawXLabels(Canvas canvas, Offset c, double wd) {
    x.forEach((xp) {
      drawTextCentered(canvas, c, xp, xLabelStyle, wd);
      c += Offset(wd, 0);
    });
  }

  void _drawYLabels(Canvas canvas, List<String> labels, List<Offset> points,
      double wd, double top) {
    var i = 0;
    labels.forEach((label) {
      final dp = points[i];
      final dy = (dp.dy - 15.0) < top ? 15.0 : -15.0;
      final ly = dp + Offset(0, dy);
      drawTextCentered(canvas, ly, label, yLabelStyle, wd);
      i++;
    });
  }

  void _drawDataPoints(
      Canvas canvas, List<Offset> points, Paint dotPaintFill, Paint linePaint) {
    points.forEach((dp) {
      canvas.drawCircle(dp, radius, dotPaintFill);
      canvas.drawCircle(dp, radius, linePaint);
    });
  }

  Path _computePath(List<Offset> points, double h, double w, bool cp,
      double leftPadding, double rightPadding) {


    Path path = Path();
   
    for (var i = 0; i < points.length; i++) {
      final p = points[i];
      if (i == 0) {
        path.moveTo(p.dx, p.dy);
        path.lineTo(p.dx, p.dy);
      } else {
        path.lineTo(p.dx, p.dy);
      }
    }

    return path;
  }

  List<Offset> _computePoints(
      Offset c, double width, double height, double hr) {
    List<Offset> points = [];
    y.forEach((yp) {
      final yy = height - (yp - min) * hr;
      final dp = Offset(c.dx, c.dy - height / 2.0 + yy);
      points.add(dp);
      c += Offset(width, 0);
    });
    return points;
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return true;
  }

  final Paint outlinePaint = Paint()
    ..strokeWidth = 1.0
    ..style = PaintingStyle.stroke
    ..color = Colors.white;
  void _drawOutline(Canvas canvas, Offset c, double width, double height) {
    y.forEach((p) {
      final rect = Rect.fromCenter(center: c, width: width, height: height);
      canvas.drawRect(rect, outlinePaint);
      c += Offset(width, 0);
    });
  }

  List<String> _computeLabels() {
    return y.map((yp) => yp.toStringAsFixed(1)).toList();
  }

  TextPainter measureText(
      String s, TextStyle style, double maxwidth, TextAlign align) {
    final span = TextSpan(text: s, style: style);
    final tp = TextPainter(
        text: span, textAlign: align, textDirection: TextDirection.ltr);
    tp.layout(minWidth: 0, maxWidth: maxwidth);
    return tp;
  }

  Size drawTextCentered(
      Canvas canvas, Offset c, String text, TextStyle style, double maxwidth) {
    final tp = measureText(text, style, maxwidth, TextAlign.center);
    final offset = c + Offset(-tp.width / 2.0, -tp.height / 2.0);
    tp.paint(canvas, offset);
    return tp.size;
  }
}

In cubicTO() Method we assign 3 points one for control points to draw a curve . and One for Starting point and another for end point I'm confused about points and math

0

There are 0 answers