Widgets for beautiful graphic data structures, such as force-oriented diagrams.
20240402_045325.2.mp4
Data converter: convert business data into graphic view data.
Algorithm: calculate vertex layout.
- Force directed algorithm.
- Random algorithm (In example folder).
- Support algorithm decorator.
- Breathe decorator (optional).
- Provide decorators that follow Hooke's Law for related nodes
- Provide a decorator for Hooke's Law from the center outward for all nodes
- Provide mutually exclusive Coulomb's law decorators for subgraph root nodes
- Hooke's Law decorator that provides border buffering collisions for all nodes
- Add a counter decorator in the figure to convert node forces into motion
Data panel embedding.
Style configuration.
More graphical interactions.
flutter pub add flutter_graph_view// Copyright (c) 2023- All flutter_graph_view authors. All rights reserved.//// This source code is licensed under Apache 2.0 License.import'dart:math';
import'package:flutter/material.dart';
import'package:flutter_graph_view/flutter_graph_view.dart';
classDecoratorDemoextendsStatelessWidget {
constDecoratorDemo({super.key});
@overrideWidgetbuild(BuildContext context) {
var vertexes =<Map>{};
var r =Random();
for (var i =0; i <150; i++) {
vertexes.add(
{
'id':'node$i',
'tag':'tag${r.nextInt(9)}',
'tags': [
'tag${r.nextInt(9)}',
if (r.nextBool()) 'tag${r.nextInt(4)}',
if (r.nextBool()) 'tag${r.nextInt(8)}'
],
},
);
}
var edges =<Map>{};
for (var i =0; i <150; i++) {
edges.add({
'srcId':'node${i % 8 + 8}',
'dstId':'node$i',
'edgeName':'edge${r.nextInt(3)}',
'ranking':DateTime.now().millisecond,
});
}
// for (var i = 0; i < 20; i++) {// edges.add({// 'srcId': 'node${i % 8}',// 'dstId': 'node${r.nextInt(150)}',// 'edgeName': 'edge${r.nextInt(3)}',// 'ranking': DateTime.now().millisecond,// });// }var data = {
'vertexes': vertexes,
'edges': edges,
};
returnFlutterGraphWidget(
data: data,
algorithm:RandomAlgorithm(
decorators: [
CoulombDecorator(),
// HookeBorderDecorator(),HookeDecorator(),
CoulombCenterDecorator(),
HookeCenterDecorator(),
ForceDecorator(),
ForceMotionDecorator(),
TimeCounterDecorator(),
],
),
convertor:MapConvertor(),
options:Options()
..enableHit =false
..panelDelay =constDuration(milliseconds:500)
..graphStyle = (GraphStyle()
// tagColor is prior to tagColorByIndex. use vertex.tags to get color
..tagColor = {'tag8':Colors.orangeAccent.shade200}
..tagColorByIndex = [
Colors.red.shade200,
Colors.orange.shade200,
Colors.yellow.shade200,
Colors.green.shade200,
Colors.blue.shade200,
Colors.blueAccent.shade200,
Colors.purple.shade200,
Colors.pink.shade200,
Colors.blueGrey.shade200,
Colors.deepOrange.shade200,
])
..useLegend =true// default true
..edgePanelBuilder = edgePanelBuilder
..vertexPanelBuilder = vertexPanelBuilder
..edgeShape =EdgeLineShape() // default is EdgeLineShape.
..vertexShape =VertexCircleShape(), // default is VertexCircleShape.
);
}
WidgetedgePanelBuilder(Edge edge, Viewfinder viewfinder) {
var c = viewfinder.localToGlobal(edge.position);
returnStack(
children: [
Positioned(
left: c.x +5,
top: c.y,
child:SizedBox(
width:200,
child:ColoredBox(
color:Colors.grey.shade900.withAlpha(200),
child:ListTile(
title:Text(
'${edge.edgeName} @${edge.ranking}\nDelay controlled by \noptions.panelDelay\ndefault to 300ms'),
),
),
),
)
],
);
}
WidgetvertexPanelBuilder(hoverVertex, Viewfinder viewfinder) {
var c = viewfinder.localToGlobal(hoverVertex.cpn!.position);
returnStack(
children: [
Positioned(
left: c.x + hoverVertex.radius +5,
top: c.y -20,
child:SizedBox(
width:120,
child:ColoredBox(
color:Colors.grey.shade900.withAlpha(200),
child:ListTile(
title:Text(
'Id: ${hoverVertex.id}',
),
subtitle:Text(
'Tag: ${hoverVertex.data['tag']}\nDegree: ${hoverVertex.degree} ${hoverVertex.prevVertex?.id}'),
),
),
),
)
],
);
}
}
flutter_graph_view is under the Apache License, Version 2.0.


