Adding nodes? #9
Replies: 6 comments 11 replies
-
Maybe you can try adding nodes directly to the graph, then do refresh. But there is currently no example code for this method, so I'm not sure if it works in practice either. https://github.com/graph-cn/flutter_graph_view/blob/main/lib/widgets/vertex_component.dart#L176-L176 |
Beta Was this translation helpful? Give feedback.
-
The code below will add a node to the graph. The graph will then refresh automatically and repaint. I was wondering if there would be a way to sneak a new node into the graph without triggering the repaint. Especially if one has just arranged the graph in a way that all the nodes are visible it would be great if adding a node would preserve the state. import 'dart:math';
import 'package:flutter/material.dart';
import 'package:flutter_graph_view/core/algorithm/force_directed.dart';
import 'package:flutter_graph_view/core/convertor/map_convertor.dart';
import 'package:flutter_graph_view/core/options.dart';
import 'package:flutter_graph_view/core/options/style/graph_style.dart';
import 'package:flutter_graph_view/flutter_graph_widget.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return const MaterialApp(
home: MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
late var data;
@override
void initState() {
var vertexes = <Map>{};
var r = Random();
for (var i = 0; i < 50; 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 < 50; i++) {
edges.add({
'srcId': 'node${i % 4}',
'dstId': 'node$i',
'edgeName': 'edge${r.nextInt(3)}',
'ranking': r.nextInt(DateTime.now().millisecond),
});
}
for (var i = 0; i < 50; i++) {
edges.add({
'srcId': 'node1',
'dstId': 'node2',
'edgeName': 'edge${r.nextInt(3)}',
'ranking': r.nextInt(DateTime.now().millisecond),
});
}
data = {
'vertexes': vertexes,
'edges': edges,
};
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(),
body: FlutterGraphWidget(
data: data,
algorithm: ForceDirected(),
convertor: MapConvertor(),
options: Options()
..enableHit = false
..onVertexTapUp = ((vertex, event) {
// new data render to graph
return data;
})
..panelDelay = const Duration(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
),
floatingActionButton: FloatingActionButton(
onPressed: _addData,
tooltip: 'Add node',
child: const Icon(Icons.add),
), // This trailing comma makes auto-formatting nicer for build methods.
);
}
void _addData() {
int number = DateTime.now().millisecond;
data['vertexes'].add( {
'id': 'node_ADDED_$number',
'tag': 'tag1',
'tags': [ 'tag1' ],
},);
setState(() {
data['edges'].add({
'srcId': 'node1',
'dstId': 'node_ADDED_$number',
'edgeName': 'New edge',
'ranking': 2,
});
});
}
}
|
Beta Was this translation helpful? Give feedback.
-
Thanks for the hint. I took the refreshData function as a starting point to addData like in the code below. When I use this function to add data to an existing graph I get an exception here: I will have to look into this in more detail in the coming days. Thanks a lot for you help so far! import 'package:flutter_graph_view/core/options.dart';
import 'package:flutter_graph_view/widgets/edge_component.dart';
import 'package:flutter_graph_view/widgets/graph_component.dart';
import 'package:flutter_graph_view/widgets/vertex_component.dart';
class GraphComponent2 extends GraphComponent {
GraphComponent2(
{required super.data,
required super.algorithm,
required super.context,
required super.convertor,
Options? options});
void addData(data, newData) {
// ignore: invalid_use_of_internal_member
graph = convertor.convertGraph(data);
graph.vertexes = graph.vertexes.toSet().toList()
..sort((key1, key2) => key1.degree - key2.degree > 0 ? -1 : 1);
setDefaultVertexColor();
algorithm.onGraphLoad(graph);
for (var vertexData in newData['vertexes']) {
var vertex = convertor.convertVertex(vertexData, graph);
var vc = VertexComponent(
vertex,
graph,
context,
algorithm,
options: options,
graphComponent: this,
)..scaleNotifier = scale;
vertex.cpn = vc;
world.add(vc);
for (var edgeData in newData['edges']) {
var edge = convertor.convertEdge(edgeData, graph);
var ec = EdgeComponent(edge, graph, context)..scaleNotifier = scale;
edge.cpn = ec;
world.add(ec);
}
}
}
}
|
Beta Was this translation helpful? Give feedback.
-
I just send you a PR with the PersistenceDecorator implementation. It would be cool if one could earmark manually adjusted positions and then let the other nodes continue to float. But for the purpose of adding nodes this could be a first step. Over the next days I will take a look if I find a possibility to add nodes... 😃 |
Beta Was this translation helpful? Give feedback.
-
I just submitted a fix the PR so that the cache gets updated. I used the decorator to pull out the position information, store them in JSON and thereby be able to save different configurations of the graph - quite a nice feature / side effect. |
Beta Was this translation helpful? Give feedback.
-
@jersonal-com Three interfaces, |
Beta Was this translation helpful? Give feedback.
-
Thanks a lot for providing an awesome package.
I was wondering if you have some sample code for adding nodes while the graph is displayed.
If I read the code right, then there is an update function in the graph component that would accept new data. How would I access that method?
Thanks a lot in advance!
Beta Was this translation helpful? Give feedback.
All reactions