Graphite Flutter Library

repository·master·Indexed 41 days ago

https://github.com/lempiy/flutter_graphite

A Flutter library for rendering direct graphs, trees, and flowcharts using a rectangular layout system. It provides the DirectGraph and GraphiteCanvas widgets, supporting horizontal and vertical orientations, custom node builders, edge labels, and extensive gesture support for nodes and edges.

Tokens
4K
Snippets
17
Records
20
Agent score
52%

What's inside Graphite

  1. Use Graphite to draw direct graphs, trees, and flowcharts

    master

    Graphite is a Flutter widget designed for drawing direct graphs, trees, and flowcharts in a rectangular layout. It supports both horizontal and vertical orientations and allows for high levels of customization, including custom node builders, edge labels, and custom painting for edges.

    import 'package:graphite/graphite.dart';
  2. Graphite features and customization options

    master

    Graphite provides several customization hooks for building complex graph UIs:

    • Layout: Control the building direction (horizontal or vertical) via orientation.
    • Nodes: Use a custom builder to provide your own widget for nodes and handle node/edge gesture events.
    • Edges: Provide a custom paint builder for edges, customize arrows and lines, and add edge text or Widget labels.
    • Overlays: Ability to add overlays to the graph structure.
  3. Customize iOS launch screen assets

    master

    To change the launch screen image for the iOS version of your Flutter application, you can use one of two methods:

    Method 1: Direct File Replacement

    Replace the existing image files located in the example/ios/Runner/Assets.xcassets/LaunchImage.imageset/ directory with your own assets. Ensure the new files match the expected naming and format requirements of the project.

    Method 2: Using Xcode

    1. Open the iOS workspace by running open ios/Runner.xcworkspace from your terminal.
    2. In the Xcode Project Navigator, navigate to Runner/Assets.xcassets.
    3. Locate the LaunchImage asset set.
    4. Drag and drop your desired images directly into the asset set in the Xcode interface.
    open ios/Runner.xcworkspace
  4. Implement a DirectGraph widget

    master

    To render a graph, use the DirectGraph widget. You must provide a list of nodes parsed via nodeInputFromJson. The widget can be wrapped in an InteractiveViewer with constrained: false to allow for panning and zooming across a large graph area.

    Key properties:

    • list: The graph structure parsed from JSON using nodeInputFromJson.
    • defaultCellSize: A Size object defining the dimensions of the graph cells.
    • cellPadding: EdgeInsets defining the space between cells.
    • orientation: Determines the layout direction using MatrixOrientation (e.g., MatrixOrientation.Vertical or MatrixOrientation.Horizontal).
    import 'package:flutter/material.dart';
    import 'package:graphite/graphite.dart';
    
    // Example JSON structure for nodes
    const list = '['
        '{"id":"A","next":[{"outcome":"B"}]},\' 
        '{"id":"B","next":[{"outcome":"C"},{"outcome":"D"}]}'
        ']';
    
    // Inside your build method
    DirectGraph(
      list: nodeInputFromJson(list),
      defaultCellSize: const Size(100.0, 100.0),
      cellPadding: const EdgeInsets.all(20),
      orientation: MatrixOrientation.Vertical,
    )
  5. Customize edge appearance with EdgeStyle

    master

    The EdgeStyle class allows you to define the visual properties of edges in the graph, including line styles, colors, and arrowheads.

    Properties

    • lineStyle: The pattern of the line. Options: LineStyle.solid, LineStyle.dashed, LineStyle.dotted, or LineStyle.dashDotted.
    • linePaint: The Paint object used for drawing. Defaults to a black stroke with width 2.
    • borderRadius: The border radius for edge angles.
    • dashLength: Length of dashes (used in dashed and dashDotted).
    • gapLength: Length of gaps (used in dotted, dashed, and dashDotted).
    • dotLength: Diameter of dots (used in dotted and dashDotted).
    • arrowType: The type of arrowheads to use (e.g., EdgeArrowType.one).
    • tipLength: The length (in pixels) of the two lines making the arrow tip.
    • tipAngle: The angle (in radians) between the arrow lines and the curve.

    Note: tipLength and tipAngle are ignored if a custom pathBuilder is provided.

    EdgeStyle(
      lineStyle: LineStyle.dashed,
      linePaint: Paint()..color = Colors.blue..strokeWidth = 3,
      dashLength: 15,
      gapLength: 10,
      arrowType: EdgeArrowType.one,
    );
  6. Configure edge labels with EdgeLabels

    master

    Use the EdgeLabels class to draw widgets (labels) on top of or above edges to annotate relationships between entities. You can control the alignment and the priority of the label's position relative to the edge path.

    Configuration Options

    • builder: A EdgeLabelBuilder function that returns a Widget. It provides the BuildContext, the Edge being labeled, and a bool isVertical indicating the edge's orientation.
    • alignment: Determines if the label is drawn before (EdgeLabelTextAlignment.before) or after (EdgeLabelTextAlignment.after) the edge's line. The default is EdgeLabelTextAlignment.before.
    • positionPriority: Controls how the label sticks to the edge path:
      • EdgeLabelPositionPriority.horizontal: Sticks to the horizontal line inside the edge path if possible.
      • EdgeLabelPositionPriority.vertical: Sticks to the vertical line inside the edge path if possible.
      • EdgeLabelPositionPriority.none: The default. It sticks to the vertical line if the graph orientation is MatrixOrientation.Horizontal, and to the horizontal line if the orientation is MatrixOrientation.Vertical.
    EdgeLabels(
      builder: (context, edge, isVertical) {
        return Text('Relationship');
      },
      alignment: EdgeLabelTextAlignment.after,
      positionPriority: EdgeLabelPositionPriority.horizontal,
    );
  7. Listen to GraphiteCanvas gesture streams

    master

    The GraphiteCanvas state provides a method addStreamListener that allows you to subscribe to a broadcast stream of all gestures occurring on the canvas. This is useful for implementing global gesture handling that isn't covered by specific callback properties.

    // Assuming you have access to the GraphiteCanvasState
    await graphiteCanvasState.addStreamListener((Gesture gesture) {
      // Handle custom gesture logic
    });
    await graphiteCanvasState.addStreamListener((Gesture gesture) {
      // Handle custom gesture logic
    });
  8. Handle interactions with nodes and edges

    master

    The DirectGraph widget provides extensive gesture callbacks for both nodes and edges.

    Node Gestures

    Nodes support standard GestureDetector events including:

    • onNodeTapDown, onNodeTapUp
    • onNodeLongPressStart, onNodeLongPressEnd, onNodeLongPressMoveUpdate
    • onNodeForcePress... (Start, End, Peak, Update)
    • onNodePan... (Start, Update, Down) for dragging nodes
    • onNodeSecondaryTapDown, onNodeSecondaryTapUp

    Edge Gestures

    Edges have a hitbox that is twice as wide as the edge width to improve user experience. They support:

    • onEdgeTapDown, onEdgeTapUp
    • onEdgeLongPress... (Start, End, MoveUpdate)
    • onEdgeForcePress... (Start, End, Peak, Update)
    • onEdgeSecondaryTapDown, onEdgeSecondaryTapUp

    Note: Pan/drag events are not provided for edges to avoid conflict with the InteractiveViewer pan gestures.

    Canvas Gestures

    • onCanvasTap: Triggered when tapping any point on the canvas. Useful for dismissing overlays like tooltips.
  9. Use GraphiteCanvas for custom graph drawing

    master

    GraphiteCanvas is the primary widget for rendering a graph composed of nodes and edges. It manages the layout of nodes within a Matrix, handles edge drawing, and provides extensive gesture support for both nodes and edges.

    Key Configuration Properties

    Layout & Scaling

    • matrix: The Matrix object defining the graph structure.
    • defaultCellSize: The base Size for cells.
    • cellPadding: EdgeInsets applied to cells.
    • orientation: MatrixOrientation (Horizontal or Vertical).
    • minScale / maxScale: Zoom constraints.
    • contactEdgesDistance: Distance used for edge connection points.

    Customization Builders

    • builder: A NodeCellBuilder to define how individual nodes are rendered.
    • overlayBuilder: An OverlayBuilder to render custom widgets on top of the graph (e.g., tooltips or selection highlights).
    • styleBuilder: An EdgeStyleBuilder to customize the visual appearance of edges.
    • pathBuilder: An EdgePathBuilder to customize the geometric path of edges.
    • edgeLabels: Configuration for displaying text labels on edges.

    Gesture Callbacks GraphiteCanvas supports a wide range of gestures for nodes, edges, and the canvas background, including:

    • Tap: onNodeTapDown, onNodeTapUp, onEdgeTapDown, onEdgeTapUp, onCanvasTap.
    • Secondary Tap: onNodeSecondaryTapDown, onNodeSecondaryTapUp, onEdgeSecondaryTapDown, onEdgeSecondaryTapUp.
    • Long Press: onNodeLongPressStart, onNodeLongPressEnd, onNodeLongPressMoveUpdate, onEdgeLongPressStart, etc.
    • Force Press: onNodeForcePressStart, onNodeForcePressPeak, onEdgeForcePressPeak, etc.
    • Pan: onNodePanStart, onNodePanUpdate, onNodePanDown.

    Implementation Example

    GraphiteCanvas(
      matrix: myMatrix,
      defaultCellSize: Size(100, 50),
      cellPadding: EdgeInsets.all(8.0),
      contactEdgesDistance: 5.0,
      orientation: MatrixOrientation.Horizontal,
      maxScale: 3.0,
      minScale: 0.5,
      clipBehavior: Clip.none,
      builder: (context, node) {
        return MyCustomNodeWidget(node: node);
      },
      onNodeTapDown: (node) {
        print('Tapped node: ${node.id}');
      },
      onCanvasTap: () {
        print('Canvas tapped');
      },
    );
  10. Use the DirectGraph widget to draw graphs

    master

    The DirectGraph widget is the primary entry point for rendering direct graphs in Flutter. It takes a list of NodeInput objects as its source and handles the layout, rendering, and interaction logic.

    Key Configuration Options

    • list: A List<NodeInput> defining the graph nodes and their connections.
    • defaultCellSize: The default size for nodes where NodeInput.size is not specified.
    • cellPadding: Padding between nodes. Increasing this increases edge lengths.
    • orientation: Determines the layout direction. Use MatrixOrientation.Horizontal (default) for row views or MatrixOrientation.Vertical for column views.
    • centered: If true, node outcomes are centered relative to their parent as much as possible in rectangular space (useful for tree-like structures).
    • maxScale / minScale: Controls the zoom limits within the internal InteractiveViewer (defaults to 2.5 and 0.25 respectively).

    Customization via Builders

    • nodeBuilder: A function to render custom node widgets. It provides a MatrixNode containing node information.
    • overlayBuilder: A function to render custom widgets on top of the graph (e.g., tooltips or detail panels). It provides information about all current nodes and edges and expects a Positioned widget to be returned.
    • styleBuilder: Provides custom EdgeStyle for edges, called on each canvas render cycle.
    • pathBuilder: Allows defining custom Path shapes for edges. Note: if this is set, arrows at the tips of paths will not be added.
    • edgeLabels: Used to draw labels on or above edges to describe relations.
    DirectGraph(
      list: myNodeInputs,
      defaultCellSize: Size(100, 50),
      cellPadding: EdgeInsets.all(20),
      orientation: MatrixOrientation.Horizontal,
      nodeBuilder: (node) => MyCustomNodeWidget(node),
      overlayBuilder: (nodes, edges) => MyTooltip(nodes, edges),
    );
  11. Define custom edge paths with EdgePathBuilder

    master

    If the standard EdgeStyle is insufficient, you can provide a custom EdgePathBuilder to define exactly how an edge's path is drawn. This overrides the default arrow tip calculations.

    An EdgePathBuilder is a function with the following signature: Path Function(NodeInput income, NodeInput node, List<List<double>> points, EdgeStyle style)