'i need to get a sankey diagram or arrow shape

Hey i need to drow a sample sankey diagram because i can't find any one like that in syncfusion_flutter_charts or fl_chart so i started to write a class it will give me the same Diagrame but i can't makee the same shape can anyone helpe me by any idea, i will be greatful. i need some thing like this pic.

enter image description here

 class sankey_diagram extends StatefulWidget {
  sankey_diagram({required this.size});
  double size;
  @override
  State<sankey_diagram> createState() => _sankey_diagramState(size: size);
}

class _sankey_diagramState extends State<sankey_diagram> {
  _sankey_diagramState({required this.size});
  double size;
  int? id;
  double ratio = 29;
  @override
  Widget build(BuildContext context) {
    id = context.watch<indexDashboard>().getvesselid();
    return ListView(children: [
      Card(
        child: Row(
          crossAxisAlignment: CrossAxisAlignment.start,
          children: [
            Container(
                width: 100,
                height: size,
                decoration: const BoxDecoration(
                    // borderRadius: BorderRadius.only(topLeft: Radius.circular(10.0),bottomLeft: Radius.circular(10.0)),
                    color: Colors.orange)),
            Column(children: [
              Container(
                width: 130,
                height: size * (ratio / 100),
                decoration: BoxDecoration(
                  color: get_color(ratio),
                ),
              ),
              Container(
                width: 130,
                height: size * ((100.0 - ratio) / 100),
                decoration: BoxDecoration(
                    borderRadius: BorderRadius.only(
                      topRight: Radius.circular(size * ((100.0 - ratio) / 100)),
                    ),
                    color: get_color((100.0 - ratio))),
              ),
              Container(
                padding: EdgeInsets.only(left: 25),
                child: Container(
                  width: 85,
                  height: 25,
                  decoration: BoxDecoration(color: get_color((100.0 - ratio))),
                ),
              ),
              Container(
                padding: EdgeInsets.only(left: 25),
                child: Container(
                  width: 100,
                  height: size * ((100.0 - ratio) / 100),
                  decoration: BoxDecoration(
                      borderRadius: BorderRadius.only(
                        bottomLeft:
                            Radius.circular(size * ((100.0 - ratio) / 100)),
                        bottomRight:
                            Radius.circular(size * ((100.0 - ratio) / 100)),
                      ),
                      color: get_color((100.0 - ratio))),
                ),
              ),
            ]),
            Column(
              children: [
                SizedBox(
                  height: 10,
                ),
                Container(
                  width: 30,
                  height: size * (ratio / 100) - 20,
                  decoration: BoxDecoration(
                    color: get_color(ratio),
                  ),
                ),
              ],
            ),
            Container(
              width: 30,
              height: size * (ratio / 100),
              decoration: BoxDecoration(
                borderRadius: BorderRadius.only(
                    topRight: Radius.circular(size * (ratio / 100)),
                    bottomRight: Radius.circular(size * (ratio / 100))),
                color: get_color(ratio),
              ),
            ),
          ],
        ),
      ),
    ]);
  }
}

Color get_color(double ratio) {
  if (ratio <= 30) {
    return Colors.green;
  } else if (ratio > 30 && ratio <= 70) {
    return Colors.yellow;
  } else {
    return Colors.red;
  }
}

this is output from my code ...i need to know how can i get the arrow shape

enter image description here



Solution 1:[1]

I am using CustomPaint for this. Run on dartPad, you can play offset, that will improve the ui.

Painter Class

class SankyPaint extends CustomPainter {
  @override
  void paint(Canvas canvas, Size size) {
    Paint paint = Paint()..color = Colors.blue;
    final double padding = size.height * .05;

    //top arrow
    Path greenArrowPath = Path()
      ..moveTo(size.width * .4, padding * 2)
      ..lineTo(size.width * .75, padding * 2)
      ..lineTo(size.width * .75, padding / 2) //top most
      ..lineTo(size.width * .9, padding * 4) // arrow pin
      ..lineTo(size.width * .75, padding * 7.5) //bottom most
      ..lineTo(size.width * .75, padding * 6)
      ..lineTo(size.width * .4, padding * 6);

    canvas.drawPath(greenArrowPath, paint..color = Colors.green);

    Path downwardPath = Path()
      ..moveTo(
        size.width * .4,
        size.height * .45,
      )
      ..lineTo(size.width * .75, size.height * .45)
      ..quadraticBezierTo(
        //top curve
        size.width * .9,
        size.height * .45,
        size.width * .9,
        size.height * .6,
      )
      ..lineTo(size.width * .9, size.height * .8)
      ..lineTo(size.width * .95, size.height * .8) //most left
      ..lineTo(size.width * .85, size.height * .93) //bottom pin
      ..lineTo(size.width * .75, size.height * .8)
      ..lineTo(size.width * .8, size.height * .8)
      ..lineTo(size.width * .8, size.height * .6)
      ..quadraticBezierTo(
        size.width * .8,
        size.height * .55,
        size.width * .75,
        size.height * .55,
      )
      ..lineTo(
        size.width * .4,
        size.height * .55,
      );

    canvas.drawPath(downwardPath, paint..color = Colors.orange);

    //left blue  rect
    canvas.drawRect(
      Rect.fromLTRB(
        padding,
        padding * 2,
        size.width * .4,
        padding + size.height * .55,
      ),
      paint..color = Colors.blue,
    );
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) => false;
}

Use case

      SizedBox(
            width: 500,
            height: 500,
            child: CustomPaint(
              painter: SankyPaint(),
            ),
          ),

image

Solution 2:[2]

There is a flutter package called arrow_path, in that package the arrows with their paths are implemented. I think you can use this package and adjust the line thickness of the arrow you need to your requiremenets.

You can install and see examples of this package here: https://pub.dev/packages/arrow_path

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 Yeasin Sheikh
Solution 2 Abdallah Ibrahim