Flutter图形展示插件graphview的使用

发布于 1周前 作者 wuwangju 来自 Flutter

Flutter图形展示插件graphview的使用

Flutter GraphView 是一个用于展示数据结构图的插件,支持树形布局、有向图和分层图。它非常适合用于展示家族树、层次视图等。

插件概述

GraphView 支持不同的图布局,并且在小规模图中表现良好。你可以通过以下链接查看在线示例:

布局类型

树形布局(Tree Layout)

使用 Walker 算法与 Buchheim 的运行时改进 (BuchheimWalkerAlgorithm 类)。支持不同方向的布局,包括 ORIENTATION_LEFT_RIGHT, ORIENTATION_RIGHT_LEFT, ORIENTATION_TOP_BOTTOMORIENTATION_BOTTOM_TOP (默认)。你还可以设置兄弟分离、层级分离、子树分离等参数。

有向图(Directed Graph)

使用 Fruchterman 和 Reingold 提出的算法(FruchtermanReingoldAlgorithm 类),通过模拟吸引力/排斥力来绘制有向图。

分层图(Layered Graph)

使用 Sugiyama 等人提出的多层图绘制算法 (SugiyamaAlgorithm 类),利用了图的层次结构。同样支持不同的方向布局。

使用方法

目前 GraphView 需要结合缩放引擎如 InteractiveViewer 使用。为了改变缩放值,可以使用 InteractiveViewer 类中的属性。

示例代码

下面是一个完整的示例 Demo,展示了如何创建并显示一个树形图。

import 'package:flutter/material.dart';
import 'package:graphview/GraphView.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) => MaterialApp(
        home: TreeViewPage(),
      );
}

class TreeViewPage extends StatefulWidget {
  @override
  _TreeViewPageState createState() => _TreeViewPageState();
}

class _TreeViewPageState extends State<TreeViewPage> {
  final Graph graph = Graph()..isTree = true;
  BuchheimWalkerConfiguration builder = BuchheimWalkerConfiguration();

  @override
  void initState() {
    super.initState();
    setupTree();
  }

  void setupTree() {
    final node1 = Node.Id(1);
    final node2 = Node.Id(2);
    final node3 = Node.Id(3);
    final node4 = Node.Id(4);
    final node5 = Node.Id(5);
    final node6 = Node.Id(6);
    final node7 = Node.Id(7);
    final node8 = Node.Id(8);
    final node9 = Node.Id(9);
    final node10 = Node.Id(10);
    final node11 = Node.Id(11);
    final node12 = Node.Id(12);

    graph.addEdge(node1, node2);
    graph.addEdge(node1, node3, paint: Paint()..color = Colors.red);
    graph.addEdge(node1, node4, paint: Paint()..color = Colors.blue);
    graph.addEdge(node2, node5);
    graph.addEdge(node2, node6);
    graph.addEdge(node6, node7, paint: Paint()..color = Colors.red);
    graph.addEdge(node6, node8, paint: Paint()..color = Colors.red);
    graph.addEdge(node4, node9);
    graph.addEdge(node4, node10, paint: Paint()..color = Colors.black);
    graph.addEdge(node4, node11, paint: Paint()..color = Colors.red);
    graph.addEdge(node11, node12);

    builder
      ..siblingSeparation = (100)
      ..levelSeparation = (150)
      ..subtreeSeparation = (150)
      ..orientation = (BuchheimWalkerConfiguration.ORIENTATION_TOP_BOTTOM);
  }

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      body: Column(
        mainAxisSize: MainAxisSize.max,
        children: [
          Expanded(
            child: InteractiveViewer(
              constrained: false,
              boundaryMargin: EdgeInsets.all(100),
              minScale: 0.01,
              maxScale: 5.6,
              child: GraphView(
                graph: graph,
                algorithm: BuchheimWalkerAlgorithm(builder, TreeEdgeRenderer(builder)),
                paint: Paint()
                  ..color = Colors.green
                  ..strokeWidth = 1
                  ..style = PaintingStyle.stroke,
                builder: (Node node) {
                  var a = node.key.value as int;
                  return rectangleWidget(a);
                },
              ),
            ),
          ),
        ],
      ),
    );
  }

  Widget rectangleWidget(int a) {
    return InkWell(
      onTap: () {
        print('clicked');
      },
      child: Container(
        padding: EdgeInsets.all(16),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(4),
          boxShadow: [BoxShadow(color: Colors.blue[100], spreadRadius: 1)],
        ),
        child: Text('Node ${a}'),
      ),
    );
  }
}

使用 Builder 机制构建节点

你可以根据节点ID决定要显示哪个小部件。例如:

builder: (Node node) {
  var a = node.key.value as int;
  if (a == 2) {
    return rectangleWidget(a);
  } else {
    return circleWidget(a);
  }
},

设置边的颜色和厚度

你可以通过自定义 Paint 对象来设置边的颜色和厚度:

paint: Paint()..color = Colors.green..strokeWidth = 1..style = PaintingStyle.stroke,

为每条边单独设置颜色

当你添加一条边时,可以通过传递 Paint 参数来为其指定颜色:

var a = Node();
var b = Node();
graph.addEdge(a, b, paint: Paint()..color = Colors.red);

以上是关于 Flutter 图形展示插件 GraphView 的基本使用介绍及完整示例代码。希望这些信息能帮助你在项目中更好地使用 GraphView 来展示你的数据结构图。


更多关于Flutter图形展示插件graphview的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html

1 回复

更多关于Flutter图形展示插件graphview的使用的实战系列教程也可以访问 https://www.itying.com/category-92-b0.html


当然,以下是一个关于如何在Flutter中使用graphview插件进行图形展示的示例代码。graphview是一个用于在Flutter应用中展示图形(如流程图、网络图等)的流行插件。

首先,确保你已经在pubspec.yaml文件中添加了graphview依赖:

dependencies:
  flutter:
    sdk: flutter
  graphview: ^0.14.0  # 请根据需要检查最新版本号

然后,运行flutter pub get来安装依赖。

接下来是一个简单的示例,展示如何使用graphview插件来创建一个基本的图形:

import 'package:flutter/material.dart';
import 'package:graphview/graphview.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatelessWidget {
  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      title: 'GraphView Example',
      theme: ThemeData(
        primarySwatch: Colors.blue,
      ),
      home: GraphViewScreen(),
    );
  }
}

class GraphViewScreen extends StatefulWidget {
  @override
  _GraphViewScreenState createState() => _GraphViewScreenState();
}

class _GraphViewScreenState extends State<GraphViewScreen> {
  @override
  Widget build(BuildContext context) {
    // 创建一个Graph实例
    final graph = GraphBuilder.build()
      ..addNode(Node(id: 'A', label: 'Node A'))
      ..addNode(Node(id: 'B', label: 'Node B'))
      ..addNode(Node(id: 'C', label: 'Node C'))
      ..addEdge(Edge(from: 'A', to: 'B', label: 'Edge A-B'))
      ..addEdge(Edge(from: 'B', to: 'C', label: 'Edge B-C'))
      .build();

    return Scaffold(
      appBar: AppBar(
        title: Text('GraphView Example'),
      ),
      body: Padding(
        padding: const EdgeInsets.all(16.0),
        child: GraphView(
          graph: graph,
          builder: (node) {
            // 自定义节点样式
            return NodePainter(
              node: node,
              builder: (context, state) {
                return Container(
                  decoration: BoxDecoration(
                    color: Colors.white,
                    border: Border.all(color: Colors.black, width: 2),
                    borderRadius: BorderRadius.circular(10),
                  ),
                  padding: EdgeInsets.all(8),
                  child: Text(state.node.label ?? ''),
                );
              },
            );
          },
          edgePainterBuilder: (edge) {
            // 自定义边样式
            return EdgePainter(
              edge: edge,
              builder: (context, state) {
                return CustomPaint(
                  painter: LinePainter(
                    color: Colors.black,
                    strokeWidth: 2,
                    startPoint: state.fromPosition,
                    endPoint: state.toPosition,
                  ),
                );
              },
            );
          },
          layoutConfig: ForceLayoutConfig(
            nodeSpacing: 50,
            repulsion: 1000,
            edgeLength: 100,
            damping: 0.9,
            stiffness: 0.1,
          ),
        ),
      ),
    );
  }
}

// 自定义边绘制Painter
class LinePainter extends CustomPainter {
  final Color color;
  final double strokeWidth;
  final Offset startPoint;
  final Offset endPoint;

  LinePainter({
    required this.color,
    required this.strokeWidth,
    required this.startPoint,
    required this.endPoint,
  });

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = color
      ..strokeWidth = strokeWidth
      ..style = PaintingStyle.stroke;

    canvas.drawLine(startPoint, endPoint, paint);
  }

  @override
  bool shouldRepaint(covariant CustomPainter oldDelegate) {
    return oldDelegate != this;
  }
}

这个示例代码创建了一个包含三个节点(A、B、C)和两条边(A-B,B-C)的简单图。节点和边的样式可以通过自定义NodePainterEdgePainter来实现。

  • GraphBuilder用于构建图,包括添加节点和边。
  • GraphView用于在屏幕上展示图。
  • NodePainterEdgePainter用于自定义节点和边的绘制样式。

运行这个示例,你应该能看到一个基本的图形展示,你可以根据需要进一步自定义节点和边的样式以及布局配置。

回到顶部