Skip to content

Commit 2ff06bd

Browse files
committed
feat: add a series of decorators to the GraphAlgorithm.
1 parent 07e001e commit 2ff06bd

34 files changed

+33551
-32792
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
## 1.0.0
2+
- feat: add a series of decorators to the GraphAlgorithm.
3+
4+
### Behavior change:
5+
- Changed the parameter of the `GraphAlgorithm` constructor from [decorator] to {decorators}
6+
17
## 0.3.0
28
- perf: use `panelDelay` in the options to control the delay time of the display panel.
39
* fix: hover testing of edges, multiple edges and self loops

README-CN.md

Lines changed: 132 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@
1111
<a title="Pub" href="https://flame-engine.org" >
1212
<img src="https://img.shields.io/badge/Powered%20by-%F0%9F%94%A5-orange.svg" />
1313
</a>
14-
<a title="Powered by Flame" href="https://pub.flutter-io.cn/packages/flutter_graph_view" >
15-
<img src="https://img.shields.io/badge/Pub-v0.0.1+x-red?style=popout" />
14+
<a title="Powered by Flame" href="https://pub.dev/packages/flutter_graph_view" >
15+
<img src="https://img.shields.io/badge/Pub-v1.x-red?style=popout" />
1616
</a>
1717
<a href="https://github.com/dudu-ltd/flutter_graph_view/stargazers">
1818
<img src="https://img.shields.io/github/stars/dudu-ltd/flutter_graph_view" alt="GitHub stars" />
@@ -24,9 +24,11 @@
2424

2525
致力于图数据的可视化组件
2626

27-
![demo](https://foruda.gitee.com/images/1674684822685415888/5033481e_1043207.png)
27+
![输入图片说明](https://foruda.gitee.com/images/1712005397846215598/d97f4d7e_1043207.png "屏幕截图")
2828

29-
![多边节点](https://foruda.gitee.com/images/1675837598136195029/03b27259_1043207.png "屏幕截图")
29+
![输入图片说明](https://foruda.gitee.com/images/1712005408211711810/bc5a6037_1043207.png "屏幕截图")
30+
31+
![输入图片说明](https://foruda.gitee.com/images/1712005417532504522/1d44cdfe_1043207.png "屏幕截图")
3032

3133
## 特性
3234

@@ -36,6 +38,11 @@
3638
- [x] 力导向图法,雏形已实现
3739
- [x] 支持定位算法装饰器
3840
- [x] 提供呼吸效果的自定义装饰器(可选特性)
41+
- [x] 为相关连节点提供遵循胡克定律的装饰器
42+
- [x] 为所有节点提供由中心向外的胡克定律的装饰器
43+
- [x] 为子图根节点提供互斥的的库伦定律装饰器
44+
- [x] 为所有节点提供边缘缓冲碰撞的胡克定律装饰器
45+
- [x] 在图中追加一个计数器装饰器,用于将节点受力转换成运动
3946
- [x] 提供数据面板的嵌入
4047
- [x] 提供样式配置
4148
- [ ] 提供更多交互能力
@@ -58,122 +65,137 @@ import 'dart:math';
5865
import 'package:flutter/material.dart';
5966
import 'package:flutter_graph_view/flutter_graph_view.dart';
6067
61-
void main() {
62-
var vertexes = <Map>{};
63-
var r = Random();
64-
for (var i = 0; i < 200; i++) {
65-
vertexes.add(
66-
{
67-
'id': 'node$i',
68-
'tag': 'tag${r.nextInt(9)}',
69-
'tags': [
70-
'tag${r.nextInt(9)}',
71-
if (r.nextBool()) 'tag${r.nextInt(4)}',
72-
if (r.nextBool()) 'tag${r.nextInt(8)}'
68+
class DecoratorDemo extends StatelessWidget {
69+
const DecoratorDemo({super.key});
70+
71+
@override
72+
Widget build(BuildContext context) {
73+
var vertexes = <Map>{};
74+
var r = Random();
75+
for (var i = 0; i < 150; i++) {
76+
vertexes.add(
77+
{
78+
'id': 'node$i',
79+
'tag': 'tag${r.nextInt(9)}',
80+
'tags': [
81+
'tag${r.nextInt(9)}',
82+
if (r.nextBool()) 'tag${r.nextInt(4)}',
83+
if (r.nextBool()) 'tag${r.nextInt(8)}'
84+
],
85+
},
86+
);
87+
}
88+
var edges = <Map>{};
89+
90+
for (var i = 0; i < 150; i++) {
91+
edges.add({
92+
'srcId': 'node${i % 8 + 8}',
93+
'dstId': 'node$i',
94+
'edgeName': 'edge${r.nextInt(3)}',
95+
'ranking': DateTime.now().millisecond,
96+
});
97+
}
98+
// for (var i = 0; i < 20; i++) {
99+
// edges.add({
100+
// 'srcId': 'node${i % 8}',
101+
// 'dstId': 'node${r.nextInt(150)}',
102+
// 'edgeName': 'edge${r.nextInt(3)}',
103+
// 'ranking': DateTime.now().millisecond,
104+
// });
105+
// }
106+
107+
var data = {
108+
'vertexes': vertexes,
109+
'edges': edges,
110+
};
111+
return FlutterGraphWidget(
112+
data: data,
113+
algorithm: RandomAlgorithm(
114+
decorators: [
115+
CoulombDecorator(),
116+
// HookeBorderDecorator(),
117+
HookeDecorator(),
118+
CoulombCenterDecorator(),
119+
HookeCenterDecorator(),
120+
ForceDecorator(),
121+
ForceMotionDecorator(),
122+
TimeCounterDecorator(),
73123
],
74-
},
124+
),
125+
convertor: MapConvertor(),
126+
options: Options()
127+
..enableHit = false
128+
..panelDelay = const Duration(milliseconds: 500)
129+
..graphStyle = (GraphStyle()
130+
// tagColor is prior to tagColorByIndex. use vertex.tags to get color
131+
..tagColor = {'tag8': Colors.orangeAccent.shade200}
132+
..tagColorByIndex = [
133+
Colors.red.shade200,
134+
Colors.orange.shade200,
135+
Colors.yellow.shade200,
136+
Colors.green.shade200,
137+
Colors.blue.shade200,
138+
Colors.blueAccent.shade200,
139+
Colors.purple.shade200,
140+
Colors.pink.shade200,
141+
Colors.blueGrey.shade200,
142+
Colors.deepOrange.shade200,
143+
])
144+
..useLegend = true // default true
145+
..edgePanelBuilder = edgePanelBuilder
146+
..vertexPanelBuilder = vertexPanelBuilder
147+
..edgeShape = EdgeLineShape() // default is EdgeLineShape.
148+
..vertexShape = VertexCircleShape(), // default is VertexCircleShape.
75149
);
76150
}
77-
var edges = <Map>{};
78-
79-
for (var i = 0; i < 200; i++) {
80-
edges.add({
81-
'srcId': 'node${i % 4}',
82-
'dstId': 'node$i',
83-
'edgeName': 'edge${r.nextInt(3)}',
84-
'ranking': r.nextInt(DateTime.now().millisecond),
85-
});
86-
}
87-
88-
for (var i = 0; i < 50; i++) {
89-
edges.add({
90-
'srcId': 'node1',
91-
'dstId': 'node2',
92-
'edgeName': 'edge${r.nextInt(3)}',
93-
'ranking': r.nextInt(DateTime.now().millisecond),
94-
});
95-
}
96-
97-
var data = {
98-
'vertexes': vertexes,
99-
'edges': edges,
100-
};
101-
102-
runApp(MaterialApp(
103-
home: Scaffold(
104-
body: FlutterGraphWidget(
105-
data: data,
106-
algorithm: ForceDirected(BreatheDecorator()),
107-
convertor: MapConvertor(),
108-
options: Options()
109-
..graphStyle = (GraphStyle()
110-
// tagColor is prior to tagColorByIndex. use vertex.tags to get color
111-
..tagColor = {'tag8': Colors.orangeAccent.shade200}
112-
..tagColorByIndex = [
113-
Colors.red.shade200,
114-
Colors.orange.shade200,
115-
Colors.yellow.shade200,
116-
Colors.green.shade200,
117-
Colors.blue.shade200,
118-
Colors.blueAccent.shade200,
119-
Colors.purple.shade200,
120-
Colors.pink.shade200,
121-
Colors.blueGrey.shade200,
122-
Colors.deepOrange.shade200,
123-
])
124-
..useLegend = true // default true
125-
..edgePanelBuilder = edgePanelBuilder
126-
..vertexPanelBuilder = vertexPanelBuilder
127-
..edgeShape = EdgeLineShape() // default is EdgeLineShape.
128-
..vertexShape = VertexCircleShape(), // default is VertexCircleShape.
129-
),
130-
),
131-
));
132-
}
133151
134-
Widget edgePanelBuilder(Edge edge) {
135-
var c = (edge.start.cpn!.position + edge.end!.cpn!.position) / 2;
136-
return Stack(
137-
children: [
138-
Positioned(
139-
left: c.x + 5,
140-
top: c.y,
141-
child: SizedBox(
142-
width: 150,
143-
child: ColoredBox(
144-
color: Colors.white,
145-
child: ListTile(
146-
title: Text('${edge.edgeName} @${edge.ranking}'),
152+
Widget edgePanelBuilder(Edge edge, Viewfinder viewfinder) {
153+
var c = viewfinder.localToGlobal(edge.position);
154+
155+
return Stack(
156+
children: [
157+
Positioned(
158+
left: c.x + 5,
159+
top: c.y,
160+
child: SizedBox(
161+
width: 200,
162+
child: ColoredBox(
163+
color: Colors.grey.shade900.withAlpha(200),
164+
child: ListTile(
165+
title: Text(
166+
'${edge.edgeName} @${edge.ranking}\nDelay controlled by \noptions.panelDelay\ndefault to 300ms'),
167+
),
147168
),
148169
),
149-
),
150-
)
151-
],
152-
);
153-
}
170+
)
171+
],
172+
);
173+
}
154174
155-
Widget vertexPanelBuilder(hoverVertex) {
156-
return Stack(
157-
children: [
158-
Positioned(
159-
left: hoverVertex.cpn!.position.x + hoverVertex.radius + 5,
160-
top: hoverVertex.cpn!.position.y - 20,
161-
child: SizedBox(
162-
width: 120,
163-
child: ColoredBox(
164-
color: Colors.white,
165-
child: ListTile(
166-
title: Text(
167-
'Id: ${hoverVertex.id}',
175+
Widget vertexPanelBuilder(hoverVertex, Viewfinder viewfinder) {
176+
var c = viewfinder.localToGlobal(hoverVertex.cpn!.position);
177+
return Stack(
178+
children: [
179+
Positioned(
180+
left: c.x + hoverVertex.radius + 5,
181+
top: c.y - 20,
182+
child: SizedBox(
183+
width: 120,
184+
child: ColoredBox(
185+
color: Colors.grey.shade900.withAlpha(200),
186+
child: ListTile(
187+
title: Text(
188+
'Id: ${hoverVertex.id}',
189+
),
190+
subtitle: Text(
191+
'Tag: ${hoverVertex.data['tag']}\nDegree: ${hoverVertex.degree} ${hoverVertex.prevVertex?.id}'),
168192
),
169-
subtitle: Text(
170-
'Tag: ${hoverVertex.data['tag']}\nDegree: ${hoverVertex.degree}'),
171193
),
172194
),
173-
),
174-
)
175-
],
176-
);
195+
)
196+
],
197+
);
198+
}
177199
}
178200
179201
```

0 commit comments

Comments
 (0)