Flutter GraphView is used to display data in graph structures. It can display Tree layout, Directed and Layered graph. Useful for Family Tree, Hierarchy View.

Last update: Aug 10, 2022

GraphView

Get it from pub package pub points popularity likes |

Flutter GraphView is used to display data in graph structures. It can display Tree layout, Directed and Layered graph. Useful for Family Tree, Hierarchy View.

alt Example alt Example alt Example

Overview

The library is designed to support different graph layouts and currently works excellent with small graphs.

You can have a look at the flutter web implementation here: http://graphview.surge.sh/

Layouts

Tree

Uses Walker's algorithm with Buchheim's runtime improvements (BuchheimWalkerAlgorithm class). Supports different orientations. All you have to do is using the BuchheimWalkerConfiguration.orientation with either ORIENTATION_LEFT_RIGHT, ORIENTATION_RIGHT_LEFT, ORIENTATION_TOP_BOTTOM and ORIENTATION_BOTTOM_TOP (default). Furthermore parameters like sibling-, level-, subtree separation can be set.

Useful for: Family Tree, Hierarchy View, Flutter Widget Tree,

Directed graph

Directed graph drawing by simulating attraction/repulsion forces. For this the algorithm by Fruchterman and Reingold (FruchtermanReingoldAlgorithm class) was implemented.

Useful for: Social network, Mind Map, Cluster, Graphs, Intercity Road Network,

Layered graph

Algorithm from Sugiyama et al. for drawing multilayer graphs, taking advantage of the hierarchical structure of the graph (SugiyamaAlgorithm class). You can also set the parameters for node and level separation using the SugiyamaConfiguration. Supports different orientations. All you have to do is using the SugiyamaConfiguration.orientation with either ORIENTATION_LEFT_RIGHT, ORIENTATION_RIGHT_LEFT, ORIENTATION_TOP_BOTTOM and ORIENTATION_BOTTOM_TOP (default).

Useful for: Hierarchical Graph which it can have weird edges/multiple paths

Usage

Currently GraphView must be used together with a Zoom Engine like InteractiveViewer. To change the zoom values just use the different attributes described in the InteractiveViewer class.

To create a graph, we need to instantiate the Graph class. Then we need to pass the layout and also optional the edge renderer.

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> {
  @override
  Widget build(BuildContext context) {
    return Scaffold(
        body: Column(
      mainAxisSize: MainAxisSize.max,
      children: [
        Wrap(
          children: [
            Container(
              width: 100,
              child: TextFormField(
                initialValue: builder.siblingSeparation.toString(),
                decoration: InputDecoration(labelText: "Sibling Separation"),
                onChanged: (text) {
                  builder.siblingSeparation = int.tryParse(text) ?? 100;
                  this.setState(() {});
                },
              ),
            ),
            Container(
              width: 100,
              child: TextFormField(
                initialValue: builder.levelSeparation.toString(),
                decoration: InputDecoration(labelText: "Level Separation"),
                onChanged: (text) {
                  builder.levelSeparation = int.tryParse(text) ?? 100;
                  this.setState(() {});
                },
              ),
            ),
            Container(
              width: 100,
              child: TextFormField(
                initialValue: builder.subtreeSeparation.toString(),
                decoration: InputDecoration(labelText: "Subtree separation"),
                onChanged: (text) {
                  builder.subtreeSeparation = int.tryParse(text) ?? 100;
                  this.setState(() {});
                },
              ),
            ),
            Container(
              width: 100,
              child: TextFormField(
                initialValue: builder.orientation.toString(),
                decoration: InputDecoration(labelText: "Orientation"),
                onChanged: (text) {
                  builder.orientation = int.tryParse(text) ?? 100;
                  this.setState(() {});
                },
              ),
            ),
            RaisedButton(
              onPressed: () {
                final node12 = Node.Id(r.nextInt(100));
                var edge = graph.getNodeAtPosition(r.nextInt(graph.nodeCount()));
                print(edge);
                graph.addEdge(edge, node12);
                setState(() {});
              },
              child: Text("Add"),
            )
          ],
        ),
        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) {
                  // I can decide what widget should be shown here based on the id
                  var a = node.key.value as int;
                  return rectangleWidget(a);
                },
              )),
        ),
      ],
    ));
  }

  Random r = Random();

  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}')),
    );
  }

  final Graph graph = Graph()..isTree = true;
  BuchheimWalkerConfiguration builder = BuchheimWalkerConfiguration();

  @override
  void initState() {
    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 node8 = Node.Id(7);
    final node7 = 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);
  }
}

Using builder mechanism to build Nodes

You can use any widget inside the node:

Node node = Node.Id(fromNodeId) ;

builder: (Node node) {
                  // I can decide what widget should be shown here based on the id
                  var a = node.key.value as int;
                  if(a ==2)
                    return rectangleWidget(a);
                  else 
                    return circleWidget(a);
                },

Using Paint to color and line thickness

You can specify the edge color and thickness by using a custom paint

getGraphView() {
        return GraphView(
                graph: graph,
                algorithm: SugiyamaAlgorithm(builder),
                paint: Paint()..color = Colors.green..strokeWidth = 1..style = PaintingStyle.stroke,
              );
}

Color Edges individually

Add an additional parameter paint. Applicable for ArrowEdgeRenderer for now.

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

Add focused Node

You can focus on a specific node. This will allow scrolling to that node in the future, but for now , using it we can drag a node with realtime updates in force directed graph

 onPanUpdate: (details) {
        var x = details.globalPosition.dx;
        var y = details.globalPosition.dy;
        setState(() {
          builder.setFocusedNode(graph.getNodeAtPosition(i));
          graph.getNodeAtPosition(i).position = Offset(x,y);
        });
      },

Add drag nodes feature with animation

The code is there but not enabled yet due to dart null safety migration being more important

Extract info from any json to Graph Object

Now its a bit easy to use Ids to extract info from any json to Graph Object

For example, if the json is like this:

var json = {
   "nodes": [
     {"id": 1, "label": 'circle'},
     {"id": 2, "label": 'ellipse'},
     {"id": 3, "label": 'database'},
     {"id": 4, "label": 'box'},
     {"id": 5, "label": 'diamond'},
     {"id": 6, "label": 'dot'},
     {"id": 7, "label": 'square'},
     {"id": 8, "label": 'triangle'},
   ],
   "edges": [
     {"from": 1, "to": 2},
     {"from": 2, "to": 3},
     {"from": 2, "to": 4},
     {"from": 2, "to": 5},
     {"from": 5, "to": 6},
     {"from": 5, "to": 7},
     {"from": 6, "to": 8}
   ]
 };

Step 1, add the edges by using ids

  edges.forEach((element) {
      var fromNodeId = element['from'];
      var toNodeId = element['to'];
      graph.addEdge(Node.Id(fromNodeId), Node.Id(toNodeId));
    });

Step 2: Then using builder and find the nodeValues from the json using id and then set the value of that.

 builder: (Node node) {
                  // I can decide what widget should be shown here based on the id
                  var a = node.key.value as int;
                  var nodes = json['nodes'];
                  var nodeValue = nodes.firstWhere((element) => element['id'] == a);
                  return rectangleWidget(nodeValue['label'] as String);
                },

Using any widget inside the Node (Deprecated)

You can use any widget inside the node:

Node node = Node(getNodeText);

getNodeText() {
    return Container(
        padding: EdgeInsets.all(16),
        decoration: BoxDecoration(
          borderRadius: BorderRadius.circular(4),
          boxShadow: [
            BoxShadow(color: Colors.blue[100], spreadRadius: 1),
          ],
        ),
        child: Text("Node ${n++}"));
  }

Examples

Rooted Tree

alt Example

Rooted Tree (Bottom to Top)

alt Example

Rooted Tree (Left to Right)

alt Example

Rooted Tree (Right to Left)

alt Example

Directed Graph

alt Example alt Example

Layered Graph

alt Example

Inspirations

This library is basically a dart representation of the excellent Android Library GraphView by Team-Blox

I would like to thank them for open sourcing their code for which reason I was able to port their code to dart and use for flutter.

Future Works

  • Add nodeOnTap
  • Add Layered Graph
  • [] Use a builder pattern to draw items on demand.
  • [] Animations
  • [] Dynamic Node Position update for directed graph

License

MIT License

Copyright (c) 2020 Nabil Mosharraf

Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

GitHub

https://github.com/nabil6391/graphview
Comments
  • 1. Size Issue with SugiyamaAlgorithm

    There seems to be a positioning / size issue with the SugiyamaAlgorithm.

    The setup looks like:

    final _graph = Graph()..isTree = true
    
    GraphView(
                    graph: _graph,
                    algorithm: SugiyamaAlgorithm(SugiyamaConfiguration()
        ..nodeSeparation = 40
        ..levelSeparation = 50),
                    builder: (node) {
                    //_buildEdge returns a random value between 100 and 300 
                      return _buildEdge(payload!);
                    },
                  ),
    

    Check out the screenshot.

    Bildschirmfoto 2021-08-04 um 16 03 11

    Do you need any additional information from my side?

    Reviewed by stefanschaller at 2021-08-04 14:06
  • 2. How to center tree on the canvas ?

    I am using this plugin to display Family tree. And it does not center when displayed. Screenshot_20210119-202838

    I need to center horizontally like this on small tree and big family tree when first displayed : Screenshot_20210119-203319

    How to do it ?

    Reviewed by olzii at 2021-01-19 12:43
  • 3. Paint is not always complete

    I noticed with some graphs when you zoom you lose part of the painting:

    This is with graphview: ^0.6.5 Flutter (Channel beta, 1.24.0-10.2.pre, on Microsoft Windows [Version 10.0.19041.685], locale en-US)

    Screenshot (231)

    Screenshot (230)

    Reviewed by jrheisler at 2021-01-03 13:54
  • 4. Dart Migration w/o annotations

    https://github.com/nabil6391/graphview/issues/21

    Not tested, but passes analysis. I am using in my own project and will follow up with opinions.

    I used the Dart migration tools without any annotation coloring the results. Then made some patches here and there. You may want to go through it yourself as there is an opportunity to make the API a bit safer by shifting types to be non-nullable. Without annotations the migration tends to just make things explicitly null able.

    Also, probably a good idea to major version bump and add a -beta tag to the version if you feel this is still in beta.

    Reviewed by MateusAmin at 2021-03-15 22:06
  • 5. Feature request: Create graph based on data entries and provide builder argument

    Hi, thanks for building and maintaining such a great package.

    I wonder if it would be possible to allow generating a graph based on purely data classes and not widgets.

    Here's what I mean. Now nodes need to be created with widgets as their arguments:

    final node = Node(
      MyWidget(
        data: data,
      ),
      key: Key(data.id),
    );
    graph.addNode(node);
    

    What I would love to see is to be able to just provide some data or id:

    final node = NodeData(
      id: data.id
    );
    graph.addNode(node);
    

    And then when creating a GraphView I would be able to provide builder:

    GraphView(
      graph: graph,
      algorithm: g.BuchheimWalkerAlgorithm(
        g.BuchheimWalkerConfiguration(),
        g.TreeEdgeRenderer(builder),
      builder: (data){
        // I can decide what widget should be shown here
        return MyWidget(data: data);
      }
    ),
    

    This would simplify populating graph data and would abstract Flutter/material dependencies

    Reviewed by orestesgaolin at 2020-10-19 12:28
  • 6. how to let the graph scroll while has more nodes,but not zoom

    i dont want to let the graph zoom small,but want to the graph can scrool left to right,or top to bottom while i have lots of nodes to show,how can i do it?

    Reviewed by xiaobingcaicai at 2021-12-11 18:38
  • 7. Not able to connect from 2 node to 1 node

    I tried to build a graph for family tree, requirement is from father and mother i need to conenct to child(2 node to 1) using BuchheimWalkerConfiguration algorith, but I'm not able to connect like that.

    Reviewed by naaf-44 at 2021-08-17 05:42
  • 8. Graph so big nothing is visible unless zooming out, centering around `Layout.setFocusedNode` could be a fix

    Made a video of how the graph looks: https://youtu.be/-oLNpC1voJs

    You can see that the top left corner of the graph view (where the graph view seems to always start) is empty, often with every nodes and edge off-screen.

    I had to zoom out alot to be able to start seeing some graph data. If we could "focus" on the focusedNode we'd guarantee that this wouldn't happen.

    Any other suggestions on making this work so it doesn't look to the user as though there is no graph?

    Reviewed by claudiu-bele at 2021-04-07 20:19
  • 9. Index out of range

    I'm not sure if this is exactly related, but this is what happens. I am moving from 0.6.1 - 0.6.5, the orientation works fantastically, thank you. But there seems to be something going when changing out edges and nodes.

    I am driving this from a database. Data comes in, map to a list of objects that define the nodes and arrows.

    With 0.6.1 this works fine, as I am not sure what nodes I will be drawing each time, they all go away, along with the edges:

    graph.edges.clear(); graph.nodes.clear();

    I have also done this:

    List<gv.Edge> edges = [];
    graph.edges.forEach((element) {edges.add(element);});
    graph.removeEdges(edges);
    
    List<gv.Node> nodes = [];
    graph.nodes.forEach((element) {nodes.add(element);});
    graph.removeNodes(nodes);
    

    Both works great for 0.6.1

    But, 0.6.5 I get the attached error Screenshot (277)

    Reviewed by jrheisler at 2021-01-04 22:50
  • 10. Use BuchheimWalkerConfiguration to show tree merge node has problem

    I use BuchheimWalkerConfiguration like this, there are 2 branch and one merge node, it's OK

    `graph.addEdge(node1, node2, paint: Paint()..color = Colors.red); graph.addEdge(node2, node6); graph.addEdge(node6, node5);

    graph.addEdge(node2, node3); graph.addEdge(node3, node4); graph.addEdge(node4, node5);` image

    but if i change the order like this, it will show wrong connect line

    `graph.addEdge(node1, node2, paint: Paint()..color = Colors.red); graph.addEdge(node2, node3); graph.addEdge(node3, node4); graph.addEdge(node4, node5);

    graph.addEdge(node2, node6); graph.addEdge(node6, node5);` image

    Reviewed by zhangxinagjunHJH at 2020-09-24 11:58
  • 11. Handle disconnected nodes

    Is there a way to handle for nodes that aren't connected to the main branch? I guess I'm asking whether it is possible to show two disconnected networks in the same interactive viewer. Currently if not all nodes are connected they are drawn on top of each other.

    Reviewed by roberteverman at 2020-09-05 05:03
  • 12. Nodes overlap in complex graphs

    Bildschirmfoto 2022-08-03 um 10 29 54

    Hello, We use the plugin (graphview: ^1.1.1) with the Sugiyama algorithm. In more complex graphs, the individual nodes often overlap. As can be seen in the attached image, each branch is followed by a green and a red path. However, in the marked area, the red and green paths overlap.

    Do you know what could cause this problem and how to fix it?

    Reviewed by lmis-frontend at 2022-08-03 08:56
  • 13. Is it possible to position leaf nodes on the same level?

    Hello,

    I am using graphview to create an organization chart for my company. I am now wondering if it is possible to position all leaf nodes (in my case individual teams) at the same level, regardless of how long the chain of managers above the team is.

    I have considered (but not yet tested) using virtual nodes between the team and the manager to move the leaf node down X levels. Is there a better solution to my problem?

    I have created a diagram to illustrate my goal:

    Current: Screenshot 2022-07-21 at 10 55 51

    Target: Screenshot 2022-07-21 at 10 56 10

    Reviewed by mway-niels at 2022-07-21 09:01
  • 14. Same key is being used by multiple widgets in GraphView.dart

    Hi,

    I have observed that in GraphView.dart, when we pass a key to GraphView, you are passing it to both super constructor, as well as the widget being returned in build method. I think this should not be done. Because of this we are getting an issue as below:

    The following assertion was thrown while finalizing the widget tree:
    Multiple widgets used the same GlobalKey.
    The key [LabeledGlobalKey<State<GraphView>>#f63ba] was used by multiple widgets. The parents of those widgets were:
    - GraphView-[LabeledGlobalKey<State<GraphView>>#f63ba](state: _GraphViewState#22b82)
    - KeyedSubtree-[GlobalKey#0985f]
    A GlobalKey can only be specified on one widget at a time in the widget tree.
    When the exception was thrown, this was the stack:
    #0      BuildOwner._debugVerifyGlobalKeyReservation.<anonymous closure>.<anonymous closure>.<anonymous closure> (package:flutter/src/widgets/framework.dart:2868:13)
    #1      _LinkedHashMapMixin.forEach (dart:collection-patch/compact_hash.dart:614:13)
    

    Please resolve this as soon as possible. Please let me know if there is something I missed.

    Reviewed by VikasJilla at 2022-05-23 05:41
  • 15. Layered Graph can't display Loops

    I was trying to display an NFA-ε which required the edge of a grandchild to go back into it's grandparent node. Using SugiyamaAlgorithm the resulting graph isn't correct, as visible on the attached image.

    image

    Node q2 should have an edge to node q1, instead node q1 has a strange edge to itself.

    Reviewed by h80r at 2022-05-15 22:29

Related

A powerful 🚀 Android chart view / graph view library, supporting line- bar- pie- radar- bubble- and candlestick charts as well as scaling, panning and animations.
A powerful 🚀 Android chart view / graph view library, supporting line- bar- pie- radar- bubble- and candlestick charts as well as scaling, panning and animations.

⚡ A powerful & easy to use chart library for Android ⚡ Charts is the iOS version of this library Table of Contents Quick Start Gradle Maven Documentat

Aug 11, 2022
This project is used to introduce the use of flutter canvas, include draw chart, clip image's path and draw progress indicator.
This project is used to introduce the use of flutter canvas, include draw chart, clip image's path and draw progress indicator.

flutter_canvas This project is used to introduce the use of flutter canvas, include draw chart, clip image's path and draw progress indicator. draw ch

Jan 14, 2022
Stores and manages the data of your week expenses with a chart

personal_expenses_app A new Flutter project. Getting Started This project is a starting point for a Flutter application. A few resources to get you st

Dec 26, 2021
A Flutter data visualization library based on Grammar of Graphics.
A Flutter data visualization library based on Grammar of Graphics.

Graphic is now under a total refactoring. The prior available version code is here: v0.3.0 . A Flutter data visualization library based on Grammar of

Aug 12, 2022
Tiny charts 🤏 - Sparkline charts for fast data visualization on Flutter apps

Tiny charts ?? - Sparkline charts for fast data visualization on Flutter apps

Aug 3, 2022
In this project you will see how to generate charts with the data from the Firestore.
In this project you will see how to generate charts with the data from the Firestore.

FlutterChartFirestore Flutter Tutorial - Flutter Charts+Firestore Video series can be watched here https://youtu.be/HGkbPrTSndM Getting Started In thi

Jun 1, 2022
Animated radial and pie charts for Flutter
Animated radial and pie charts for Flutter

Flutter Circular Chart A library for creating animated circular chart widgets with Flutter, inspired by Zero to One with Flutter. Overview Create easi

Aug 6, 2022
Elegant OHLC Candlestick and Trade Volume charts for @Flutter
Elegant OHLC Candlestick and Trade Volume charts for @Flutter

flutter_candlesticks Elegant OHLC Candlestick and Trade Volume charts for Flutter Usage Install for Flutter with pub. Property Description data Requir

Aug 7, 2022
A powerful Flutter chart library, currently supporting Line Chart, Bar Chart, Pie Chart, Scatter Chart and Radar Chart.
A powerful Flutter chart library, currently supporting Line Chart, Bar Chart, Pie Chart, Scatter Chart and Radar Chart.

FL Chart ?? A library to draw fantastic charts in Flutter ?? Chart Types LineChart BarChart PieChart Read More Read More Read More ScatterChart RadarC

Aug 12, 2022
A beautiful bezier line chart widget for flutter that is highly interactive and configurable.
A beautiful bezier line chart widget for flutter that is highly interactive and configurable.

Bezier Chart A beautiful bezier line chart widget for flutter that is highly interactive and configurable. Features Multi bezier lines Allow numbers a

Jul 27, 2022
[reborned barcode_scan] A flutter plugin for reading 2D barcodes and QR codes.

Reborned ?? Original barcode_scan was discontinued, so barcode_scan2 was borned with sound null safety support ?? barcode_scan2 A flutter plugin for s

Aug 11, 2022
Maybe this is the best k chart in Flutter.Support drag,scale,long press,fling.And easy to use.
Maybe this is the best k chart in Flutter.Support drag,scale,long press,fling.And easy to use.

k_chart Maybe this is the best k chart in Flutter.Support drag,scale,long press,fling.And easy to use. display image gif Getting Started Install depen

Aug 2, 2022
Flutter chart library contains depth charts supporting various indicators and zooming
Flutter chart library contains depth charts supporting various indicators and zooming

flutter_k_chart 介绍 一个仿火币的flutter图表库包含深度图,支持各种指标及放大缩小、平移等操作 webdemo演示 Demo v0.1.0:下载 APK 演示 简单用例 1.在 pubspec.yaml 中添加依赖 本项目数据来自火币openApi,火币的接口可能需要翻墙,接口

Aug 1, 2022
A simple candlestick chart for flutter. Supports smooth scroll and zoom

simple_candlestick_chart A simple candlestick chart for flutter. Supports smooth

Jun 27, 2022
:bar_chart: [wip] Create beautiful, responsive, animated charts using a simple and intuitive API.
:bar_chart: [wip] Create beautiful, responsive, animated charts using a simple and intuitive API.

fcharts A work-in-progress chart library for Flutter. Until version 1.0.0 the API is subject to change drastically. Needless to say, fcharts is not pr

Jul 14, 2022
Draw dashed lines with any shape and style you want. Just like that.
Draw dashed lines with any shape and style you want. Just like that.

dashed_line Draw dashed lines with any shape and style you want. Just like that. Usage Add the dependency to your pubspec.yaml (you can see the newest

Oct 18, 2021
Track your habits day by day and check your result like the GitHub's contributions board
Track your habits day by day and check your result like the GitHub's contributions board

Habits Diary Track your habits day by day and see your result like the GitHub's contributions board Download Support If you want to support this proje

Jun 20, 2022
Charts Library for Flutter, written in Dart with Flutter.
Charts Library for Flutter, written in Dart with Flutter.

Table of Contents New in the current release Illustration of the new "iterative auto layout" feature Autolayout step 1 Autolayout step 2 Autolayout st

Aug 6, 2022
Beautiful sparkline charts for Flutter
Beautiful sparkline charts for Flutter

flutter_sparkline Beautiful sparkline charts for Flutter. Installation Install the latest version from pub. Quick Start Import the package, create a S

Jul 31, 2022