我需要一个桑基图或箭头形状

i need to get a sankey diagram or arrow shape

嘿,我需要绘制一个示例桑基图,因为我在 syncfusion_flutter_charts 或 fl_chart 中找不到任何类似的图,所以我开始写一个 class 它会给我是同一个 Diagrame,但我无法制作相同的形状,任何人都可以通过任何想法帮助我,我将不胜感激。我需要像这张照片这样的东西。

 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;
  }
}

这是我的代码的输出...我需要知道如何获得箭头形状

有一个名为 arrow_path 的 flutter 包,在该包中实现了带有路径的箭头。我想你可以使用这个包并根据你的要求调整你需要的箭头的线宽。

您可以在此处安装并查看此软件包的示例:https://pub.dev/packages/arrow_path

我正在为此使用 CustomPaint。 运行 在 dartPad 上,你可以玩 offset,那会改善 ui。

画家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;
}

用例

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