graph_flow 0.1.2 copy "graph_flow: ^0.1.2" to clipboard
graph_flow: ^0.1.2 copied to clipboard

Flutter package to enable building builders graphically.

GraphFlow #

Screenshot

GraphFlow is a powerful and flexible Flutter package for building interactive node-based editors. It provides a highly customizable canvas with support for grid backgrounds, dynamic node positioning, and a range of connection rendering styles with advanced pan & zoom functionalities. Build flowcharts, diagram editors, visual programming environments, and more – all with ease!

Pub Version
Flutter Platform

Example Usecase: #

graph_flow_pretty

Features #

  • Interactive Node Editor:
    Add, remove, and reposition node cards on a highly interactive canvas.
  • Dynamic Connections:
    Draw connections between nodes using customizable styles such as Bezier curves, straight lines, and more.
  • Advanced Pan & Zoom:
    Navigate your canvas easily using built-in support for panning and zooming with InteractiveViewer.
  • Customizable Grid Background:
    Configure grid spacing, colors, and line widths to suit your visual style.
  • Scene Persistence:
    Save and load entire scenes—including nodes, connections, and canvas offsets—via JSON for easy sharing and persistence.
  • Flexible Event Handling:
    Customize interactions with support for mouse and gesture callbacks.
  • Easy Integration:
    Extend the package with custom painters and node factories for bespoke node behaviors.

Example of a customized Editor #

Gifshowcase

Getting Started #

Installation #

Add GraphFlow to your Flutter project's pubspec.yaml file:

dependencies:
  flutter:
    sdk: flutter
  graph_flow: ^0.1.0

Then run:

flutter pub get

Basic Usage #

Below is a simple example that demonstrates how to integrate GraphFlow into your Flutter app. This sample creates a manager, adds two nodes, and displays the canvas with a grid and connection layer.

import 'dart:convert';
import 'package:flutter/material.dart';
import 'package:graph_flow/graph_flow.dart'; // Use your package's public API.
import 'package:graph_flow/src/connection_painter.dart';
import 'package:graph_flow/src/example_node.dart';
import 'package:graph_flow/src/manager.dart';
import 'package:graph_flow/src/node_canvas.dart';

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

class MyApp extends StatelessWidget {
  static int _uniqueCounter = 0;
  
  static String generateUniqueId() {
    _uniqueCounter++; 
    // Create a unique id combining a timestamp and counter.
    return '${DateTime.now().millisecondsSinceEpoch}-$_uniqueCounter';
  }
  
  const MyApp({Key? key}) : super(key: key);
  
  String getNewID() => generateUniqueId();
  
  @override
  Widget build(BuildContext context) {
    Manager manager = Manager(getNewID: getNewID);
    // Register a node type factory.
    manager.nodeFactories['ExampleNode'] = ExampleNode.fromJson;
    // Add example nodes to the manager.
    manager.addNode(ExampleNode(manager: manager, id: getNewID()));
    manager.addNode(ExampleNode(manager: manager, id: getNewID()));
    
    return MaterialApp(
      title: 'GraphFlow Demo',
      home: Scaffold(
        backgroundColor: Colors.black,
        body: Stack(
          children: [
            // Main canvas with grid and nodes.
            CanvasPage(
              manager: manager, 
              gridSpacing: 10, 
              connectionPainter: ConnectionPainter(
                manager, 
                drawingType: ConnectionDrawingType.bezier,
              ),
            ),
            // UI controls to print or input JSON.
            Align(
              alignment: Alignment.bottomRight,
              child: Builder(
                builder: (context) => Column(
                  mainAxisSize: MainAxisSize.min,
                  children: [
                    IconButton(
                      onPressed: () {
                        Map<String, dynamic> json = manager.saveSceneToJson();
                        print(
                          const JsonEncoder.withIndent('  ').convert(json),
                        );
                      },
                      icon: const Icon(Icons.print, color: Colors.white),
                    ),
                    IconButton(
                      onPressed: () {
                        final TextEditingController controller =
                            TextEditingController();
                        showDialog(
                          context: context,
                          builder: (context) {
                            return AlertDialog(
                              title: const Text('Input JSON'),
                              content: TextField(
                                controller: controller,
                                maxLines: null,
                                decoration: const InputDecoration(
                                  hintText: 'Enter JSON here',
                                ),
                              ),
                              actions: [
                                TextButton(
                                  onPressed: () => Navigator.of(context).pop(),
                                  child: const Text('Cancel'),
                                ),
                                TextButton(
                                  onPressed: () {
                                    final inputJson = jsonDecode(controller.text);
                                    manager.loadSceneFromJson(inputJson);
                                    Navigator.of(context).pop();
                                  },
                                  child: const Text('OK'),
                                ),
                              ],
                            );
                          },
                        );
                      },
                      icon: const Icon(Icons.input, color: Colors.white),
                    ),
                  ],
                ),
              ),
            ),
          ],
        ),
      ),
    );
  }
}

Advanced Usage #

GraphFlow is fully extensible. You can provide your own custom connection painters, override default callbacks for mouse and gesture events, or extend node card functionalities. For example, to use a custom connection painter:

class MyCustomPainter extends CustomPainter {
  final Manager manager;

  MyCustomPainter(this.manager);

  @override
  void paint(Canvas canvas, Size size) {
    // Your custom connection rendering logic.
  }

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

// Usage in CanvasPage:
CanvasPage(
  manager: manager,
  connectionPainter: MyCustomPainter(manager),
);

Canvas Icon Customizable Features of CanvasPage

  • Manager

    • The required Manager instance controls nodes, connection points, and overall scene state.
  • Custom Connection Painter

    • Specify a custom painter via the connectionPainter parameter.
    • If not provided, the default ConnectionPainter is used to render connection lines.
  • Mouse Region Callbacks

    • onMouseEnter: Triggered when the mouse enters the canvas area.
    • onMouseHover: Updates the manager’s mouse position and handles hover events.
    • onMouseExit: Triggered when the mouse leaves the canvas area.
  • Gesture Detector Callbacks

    • onTapDown, onTapUp, onTap: Customize how tap events are handled.
    • onLongPress: Customize long-press behavior.
    • onPanStart, onPanUpdate, onPanEnd: Handle drag (panning) events to move nodes or navigate the canvas.
  • Canvas Dimensions

    • canvasWidth & canvasHeight: Define the size of the canvas.
  • Zoom & Pan Settings

    • maxZoom & minZoom: Control the zooming capabilities of the canvas.
    • scaleFactor: Factor applied to the scaling transformation.
  • Grid Settings

    • gridSpacing: Specifies the distance between grid lines.
    • lineColor: Defines the color of the grid lines.
    • lineWidth: Sets the stroke width of the grid lines.
    • overflowSpacing: Adds extra spacing beyond the widget’s bounds to ensure complete grid coverage.

connectionIcon Customizable Features of ConnectionPainter

- **Mouse Line Activation:** Toggle the visibility of a dynamic connection line from the selected connection point to the current mouse position using the `mouseLineActive` flag.
  • Drawing Type:
    Choose from a variety of connection drawing styles via the drawingType parameter:

    • bezier – Draw a bezier curve with vertical control points.
    • straightLine – Draw a simple straight line.
    • verticalThenHorizontal – Draw a line going vertically then horizontally.
    • halfHorizontalThenVertical – Draw a path going half horizontally then vertically.
    • halfVerticalThenHorizontal – Draw a path going half vertically then horizontally.
    • bezierHorizontalThenVertical – Draw a bezier curve transitioning horizontally then vertically.
  • Mouse Line Color:
    Customize the color of the mouse-tracking connection line through the mouseLineColor property.

  • Line Thickness:
    Adjust the stroke width of the connection lines with the lineThickness setting.

  • Endpoint Radius:
    Specify the radius for the endpoint dots on connection points using the endpointRadius.

Leverage these properties to fine-tune the visual style and interaction behavior of your connection lines for building highly interactive node-based editors.

Contributing #

Contributions are very welcome and will be reviewed in sight!

License #

GraphFlow is licensed under the MIT License. See the LICENSE file for details.

Outlook #

GraphFlow is currently fresh in development. If you have any comments or wishes for this library feel free to contact me over the github or just leave a note in the flutter discord channel.

Plans:

  • Data Pipes: It is planned to add runtime data passing into the connections themselves to allow easier usage during runtime
  • More customizable Events: Events like creation, deletion and dragging of connections is to be made fully costumizable

Thank you all for using my library <3

5
likes
140
points
34
downloads

Publisher

unverified uploader

Weekly Downloads

Flutter package to enable building builders graphically.

Repository (GitHub)
View/report issues

Documentation

API reference

License

MIT (license)

Dependencies

flutter

More

Packages that depend on graph_flow