Complete hidden node logic + unhide clicked nodes
This commit is contained in:
parent
647b6ec59a
commit
6f0be98a11
|
@ -241,7 +241,7 @@ impl Spring {
|
|||
} else {
|
||||
displacement += self.margin;
|
||||
}*/
|
||||
|
||||
|
||||
if displacement.abs() < self.margin {
|
||||
displacement *= displacement.abs() / self.margin;
|
||||
}
|
||||
|
@ -273,33 +273,57 @@ impl ForceGraph {
|
|||
self.apply_repulsion();
|
||||
|
||||
for node in self.nodes.iter_mut() {
|
||||
node.body.update(dt);
|
||||
if !node.info.hidden {
|
||||
node.body.update(dt);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn with_unhidden<R>(
|
||||
&self,
|
||||
from: usize,
|
||||
to: usize,
|
||||
f: impl FnOnce(&Node, &Node) -> R,
|
||||
) -> Option<R> {
|
||||
let from = &self.nodes[from];
|
||||
let to = &self.nodes[to];
|
||||
|
||||
if from.info.hidden || to.info.hidden {
|
||||
None
|
||||
} else {
|
||||
Some(f(from, to))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_springs(&mut self) {
|
||||
for spring in self.springs.iter() {
|
||||
let from = &self.nodes[spring.from].body;
|
||||
let to = &self.nodes[spring.to].body;
|
||||
let delta = to.position - from.position;
|
||||
let force = spring.hookes_law(delta);
|
||||
self.nodes[spring.from].body.apply_force(force);
|
||||
self.nodes[spring.to].body.apply_force(-force);
|
||||
let force = self.with_unhidden(spring.from, spring.to, |from, to| {
|
||||
let delta = to.body.position - from.body.position;
|
||||
spring.hookes_law(delta)
|
||||
});
|
||||
|
||||
if let Some(force) = force {
|
||||
self.nodes[spring.from].body.apply_force(force);
|
||||
self.nodes[spring.to].body.apply_force(-force);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn apply_repulsion(&mut self) {
|
||||
for i in 1..self.nodes.len() {
|
||||
for j in i..self.nodes.len() {
|
||||
const REPULSION_CONSTANT: f32 = 50.0;
|
||||
let from = self.nodes[i - 1].body.position;
|
||||
let to = self.nodes[j].body.position;
|
||||
let delta = to - from;
|
||||
let proximity = delta.length().max(0.1);
|
||||
let force = -(REPULSION_CONSTANT / (proximity * proximity));
|
||||
let force = delta * force;
|
||||
self.nodes[i - 1].body.apply_force(force);
|
||||
self.nodes[j].body.apply_force(-force);
|
||||
let force = self.with_unhidden(i - 1, j, |from, to| {
|
||||
const REPULSION_CONSTANT: f32 = 50.0;
|
||||
let delta = to.body.position - from.body.position;
|
||||
let proximity = delta.length().max(0.1);
|
||||
let force = -(REPULSION_CONSTANT / (proximity * proximity));
|
||||
delta * force
|
||||
});
|
||||
|
||||
if let Some(force) = force {
|
||||
self.nodes[i - 1].body.apply_force(force);
|
||||
self.nodes[j].body.apply_force(-force);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -311,9 +335,10 @@ impl ForceGraph {
|
|||
let position = node.body.position;
|
||||
let children = node.info.unhide.to_owned();
|
||||
for child in children {
|
||||
let offset = Vec2::from_angle(child as f32) * 10.0;
|
||||
let child = &mut self.nodes[child];
|
||||
child.info.hidden = false;
|
||||
child.body.position = position;
|
||||
child.body.position = position + offset;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -324,6 +349,10 @@ impl ForceGraph {
|
|||
let label_color = Color::WHITE;
|
||||
|
||||
for node in self.nodes.iter() {
|
||||
if node.info.hidden {
|
||||
continue;
|
||||
}
|
||||
|
||||
ctx.draw_ring(node.body.position, radius, thickness, color);
|
||||
|
||||
let offset = node.body.position + node.info.label_offset;
|
||||
|
@ -331,42 +360,44 @@ impl ForceGraph {
|
|||
}
|
||||
|
||||
for connection in self.connections.iter() {
|
||||
let from = self.nodes[connection.from].body.position;
|
||||
let to = self.nodes[connection.to].body.position;
|
||||
let delta = to - from;
|
||||
self.with_unhidden(connection.from, connection.to, |from, to| {
|
||||
let from = from.body.position;
|
||||
let to = to.body.position;
|
||||
let delta = to - from;
|
||||
|
||||
if delta.length() < radius * 2.0 {
|
||||
continue;
|
||||
}
|
||||
if delta.length() < radius * 2.0 {
|
||||
return;
|
||||
}
|
||||
|
||||
let delta_norm = delta.normalize();
|
||||
let from = from + delta_norm * radius;
|
||||
let to = to - delta_norm * radius;
|
||||
let delta_cross = Vec2::new(delta_norm.y, -delta_norm.x);
|
||||
let delta_side = delta_cross * connection.width / 2.0;
|
||||
let delta_norm = delta.normalize();
|
||||
let from = from + delta_norm * radius;
|
||||
let to = to - delta_norm * radius;
|
||||
let delta_cross = Vec2::new(delta_norm.y, -delta_norm.x);
|
||||
let delta_side = delta_cross * connection.width / 2.0;
|
||||
|
||||
let vertices = [
|
||||
MeshVertex {
|
||||
position: from + delta_side,
|
||||
color,
|
||||
},
|
||||
MeshVertex {
|
||||
position: from - delta_side,
|
||||
color,
|
||||
},
|
||||
MeshVertex {
|
||||
position: to + delta_side,
|
||||
color,
|
||||
},
|
||||
MeshVertex {
|
||||
position: to - delta_side,
|
||||
color,
|
||||
},
|
||||
];
|
||||
let vertices = [
|
||||
MeshVertex {
|
||||
position: from + delta_side,
|
||||
color,
|
||||
},
|
||||
MeshVertex {
|
||||
position: from - delta_side,
|
||||
color,
|
||||
},
|
||||
MeshVertex {
|
||||
position: to + delta_side,
|
||||
color,
|
||||
},
|
||||
MeshVertex {
|
||||
position: to - delta_side,
|
||||
color,
|
||||
},
|
||||
];
|
||||
|
||||
let indices = [0, 1, 2, 1, 2, 3];
|
||||
let indices = [0, 1, 2, 1, 2, 3];
|
||||
|
||||
ctx.draw_indexed(&vertices, &indices);
|
||||
ctx.draw_indexed(&vertices, &indices);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -406,7 +437,19 @@ impl PanelImpl for ForceDirectedGraphPanel {
|
|||
self.size = new_size;
|
||||
}
|
||||
|
||||
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {}
|
||||
fn on_cursor_event(&mut self, kind: CursorEventKind, at: Vec2) {
|
||||
let at = at - self.size / 2.0;
|
||||
if let CursorEventKind::Deselect = kind {
|
||||
let node = self
|
||||
.graph
|
||||
.nodes
|
||||
.iter()
|
||||
.position(|node| !node.info.hidden && node.body.position.distance(at) < 6.0);
|
||||
if let Some(node) = node {
|
||||
self.graph.unhide(node);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn on_message(&mut self, msg: Message) {}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue