Skip to content

Commit de0bed9

Browse files
committed
neighbors gathering with forces
1 parent 4ab0fd4 commit de0bed9

File tree

6 files changed

+108
-16
lines changed

6 files changed

+108
-16
lines changed

config.js

+8
Original file line numberDiff line numberDiff line change
@@ -21,5 +21,13 @@ export default
2121
"dat_gui":{
2222
"enabled":true,
2323
"closed":true
24+
},
25+
"view":{
26+
"colors":{
27+
"vertices":{
28+
"default":"#228855",
29+
"highlight":"#20f046"
30+
}
31+
}
2432
}
2533
}

index.html

+9-1
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,18 @@
44
<script src="https://cdn.jsdelivr.net/npm/@svgdotjs/[email protected]/dist/svg.min.js"></script>
55
<script src="./libs/matter.min.js"></script>
66
<script src="./libs/stats.min.js"></script>
7+
<style>
8+
.dg.main {
9+
font-size: large;
10+
}
11+
.dg.main li ul{
12+
height:60px;
13+
}
14+
</style>
715
</head>
816

917
<body style="margin:0px">
10-
<script src="src/main.js?v=a0ed249079" type="module"></script>
18+
<script src="src/main.js?v=4ab0fd43959" type="module"></script>
1119

1220
</body>
1321
</html>

src/graph.js

+40-4
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
/**
22
*
33
* sent events:
4-
* - graph_vertex (add_before_edge, add_after_edge) (move) for debug
4+
* - graph_vertex (add_before_edge, add_after_edge, hover) (move) for debug
55
* - graph_edge (add)
66
*
77
* received events:
88
* - drag & drop ('dragenter', 'dragover', 'dragleave', 'drop')
99
* - graph_edge (refresh_all)
10+
* - graph_mouse (hover)
1011
*
1112
*/
1213

1314
import * as utils from "./utils.js";
1415
import config from "../config.js";
1516

16-
let graph;
17+
let graph,mg;
1718
let startup_time;
1819

1920
function init(){
@@ -33,8 +34,14 @@ function init(){
3334

3435
function onGraphVertex(e){
3536
if(e.detail.type == 'hover'){
36-
console.log(`graph> hover on ${e.detail.id} , ${e.detail.start}`);
37-
utils.send('graph_vertex',{type:'highlight',id:e.detail.id,start:e.detail.start});
37+
if(e.detail.start){
38+
console.log(`graph> hover on ${mg.vertices[e.detail.id].label}`);
39+
}
40+
utils.send('graph_vertex',{type:'hover',id:e.detail.id,start:e.detail.start,center:true});
41+
for(let id of mg.vertices[e.detail.id].neighbors){
42+
//console.log(`graph> ${mg.vertices[e.detail.id].label} <= ${mg.vertices[id].label}`);
43+
utils.send('graph_vertex',{type:'hover',id:id,start:e.detail.start,center:false,cid:e.detail.id});
44+
}
3845
}
3946
}
4047

@@ -55,6 +62,34 @@ function import_edge(edge){
5562
return res;
5663
}
5764

65+
function import_to_map_graph(graph){
66+
let res = {};
67+
res.vertices = new Map();
68+
graph.vertices.forEach(vertex => {
69+
res.vertices[vertex.id] = vertex;
70+
});
71+
res.edges = {};
72+
graph.edges.forEach(edge => {
73+
res.edges[edge.id] = edge;
74+
});
75+
for(let [vid,v] of Object.entries(res.vertices)){
76+
v.neighbors = new Set();
77+
v.in_neighbors = new Set();
78+
v.out_neighbors = new Set();
79+
for(let [eid,e] of Object.entries(res.edges)){
80+
if(e.inV == vid){
81+
v.in_neighbors.add(e.outV);
82+
v.neighbors.add(e.outV);
83+
}
84+
if(e.outV == vid){
85+
v.out_neighbors.add(e.inV);
86+
v.neighbors.add(e.inV);
87+
}
88+
}
89+
}
90+
return res;
91+
}
92+
5893
function import_graph(input){
5994
if(typeof(input.graph) != "undefined"){
6095
graph = input.graph;
@@ -78,6 +113,7 @@ function import_graph(input){
78113
vertex = import_vertex(vertex);
79114
utils.send('graph_vertex',{type:'add_after_edge',id:vertex.id,label:vertex.label,w:100,h:50});
80115
});
116+
mg = import_to_map_graph(graph);
81117
console.log(`graph> init() : import_graph() + graph_events() after ${Date.now() - startup_time} ms`);
82118
}
83119

src/gui_app.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ function init(render_physics){
1717
damping:0.05,
1818
frictionAir:0.3
1919
};
20-
var gui = new GUI( { width: 300 } );
20+
var gui = new GUI( { width: 300 } );
2121
gui.add( params, 'show physics').listen().onChange( value => {utils.send("engine",{render_physics:value})} );
2222
gui.add( params, 'show stats').listen().onChange( value => {
2323
utils.send("stats",{show:value});

src/physics_matter.js

+43-4
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
* received events:
1111
* - resize
12-
* - graph_vertex (add_before_edge)
12+
* - graph_vertex (add_before_edge, hover)
1313
* - graph_edge (add)
1414
* - engine (stiffness, damping)
1515
* - graph (clear)
@@ -24,6 +24,7 @@ import * as utils from "./../src/utils.js";
2424
import config from "./../config.js";
2525

2626
let engine;
27+
let bm;//bodies map
2728
let renderer;
2829
//lineto renderer objects
2930
let canvas,context;
@@ -129,8 +130,36 @@ function keep_vertices_horizontal(){
129130
});
130131
}
131132

133+
function bring_neighbors_close_by(){
134+
engine.world.bodies.forEach(body => {
135+
if(body.is_force_neighbors && !body.is_center){
136+
const center_body = bm[body.has_center];
137+
const diff = Matter.Vector.sub(center_body.position, body.position);
138+
const direction = Matter.Vector.normalise(diff);
139+
const distance = Matter.Vector.magnitude(diff);
140+
if(distance < 150){
141+
body.force = Matter.Vector.mult(direction,-0.02);
142+
}
143+
if(distance > 250){
144+
body.force = Matter.Vector.mult(direction,0.02);
145+
}
146+
}
147+
});
148+
}
149+
132150
function apply_custom_forces(){
133151
keep_vertices_horizontal();
152+
bring_neighbors_close_by();
153+
}
154+
155+
function vertex_hover(d){
156+
const body = bm[d.id];
157+
//console.log(`phy> updating ${body.label}`);
158+
body.is_force_neighbors = d.start;
159+
body.is_center = d.center;
160+
if(!d.center){
161+
body.has_center = d.cid;
162+
}
134163
}
135164

136165
let last_run = 0;
@@ -200,19 +229,28 @@ function run(){
200229
function vertex_add(params){
201230
let x = params.w/2 + Math.round((physics_element.offsetWidth-params.w) * Math.random());
202231
let y = params.h/2 + Math.round((physics_element.offsetHeight-2*params.h) * Math.random());
203-
let box = Matter.Bodies.rectangle(x,y,params.w,params.h,{id:params.id,label:params.label ,isvertex:true});
232+
let body = Matter.Bodies.rectangle(x,y,params.w,params.h,{id:params.id,label:params.label ,isvertex:true});
204233

205234
let frictionAir = localStorage.getItem("frictionAir");
206-
box.frictionAir = (frictionAir === null)?0.3:frictionAir;
235+
body.frictionAir = (frictionAir === null)?0.3:frictionAir;
236+
body.is_force_neighbors = false;
237+
body.is_center = false;
207238
//console.log(`phy> ${params.label} has frictionAir at ${frictionAir}`);
208-
Matter.World.addBody(engine.world,box);
239+
Matter.World.addBody(engine.world,body);
240+
if(typeof(bm) == "undefined"){
241+
bm = new Map();
242+
}
243+
bm[params.id] = body;
209244
}
210245

211246
function onMatterVertex(e){
212247
const d = e.detail;
213248
if(d.type == 'add_before_edge'){
214249
vertex_add(d);
215250
}
251+
if(d.type == 'hover'){
252+
vertex_hover(d);
253+
}
216254
}
217255

218256
function edge_add(params){
@@ -243,6 +281,7 @@ function graph_clear(){
243281
if(config.physics.move_objects_with_mouse){
244282
Matter.World.add(engine.world, mouseConstraint);
245283
}
284+
bm = new Map();
246285
}
247286

248287
function onMatterEdge(e){

src/view_svg.js

+7-6
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
/**
22
* received events:
3-
* - graph_vertex (add, move)
3+
* - graph_vertex (add, move, hover)
44
* - graph_edge (add)
55
* - graph (clear)
66
*/
77

88
import * as utils from "./../src/utils.js";
9+
import config from "./../config.js";
910

1011
let draw;
1112
let width = 100;
@@ -27,7 +28,7 @@ function vertex_add(id,label){
2728
let vert = draw
2829
.rect(width,height)
2930
.id('vert_'+id)
30-
.attr({ fill: '#00af06' })
31+
.attr({ fill: config.view.colors.vertices.default })
3132
.on([ 'click', 'mouseover',
3233
'mouseleave','contextmenu',
3334
'touchstart','touchend'], onMouseVertex);
@@ -131,12 +132,12 @@ function graph_clear(){
131132
function vertex_highlight(id,start){
132133
let vertex = SVG('#vert_'+id);
133134
if(start){
134-
vertex.css('fill','#b00f06');
135+
vertex.css('fill',config.view.colors.vertices.highlight);
135136
}
136137
else{
137-
vertex.css('fill','#228855');
138+
vertex.css('fill',config.view.colors.vertices.default);
138139
}
139-
console.log(`svg> highlight , ${start}`);
140+
//console.log(`svg> highlight , ${start}`);
140141

141142
}
142143

@@ -151,7 +152,7 @@ function onViewVertex(e){
151152
else if(e.detail.type == "add_after_edge"){
152153
vertex_readd(d.id,d.label);
153154
}
154-
else if(e.detail.type == "highlight"){
155+
else if(e.detail.type == "hover"){
155156
vertex_highlight(d.id,d.start);
156157
}
157158
}

0 commit comments

Comments
 (0)