Skip to content

Commit ec96cea

Browse files
committed
highlight path on edge hover
1 parent e055eae commit ec96cea

File tree

5 files changed

+80
-8
lines changed

5 files changed

+80
-8
lines changed

README.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -66,6 +66,8 @@ What is already available
6666
* shadows and light filters
6767
* inline html and css with classes
6868
* Mouse and Touch
69+
* Highlight neighbors on vertex hover
70+
* Highlight path on edge hover
6971
* Drag Node position with touch
7072
* Context menu (touch empty area, then second touch on Node)
7173
* Hover states with touch Node then touch empty area
@@ -123,6 +125,8 @@ Style in js :
123125
* collect muliple css rules in one litteral string
124126
* optionally add support for .dot import with [graphlib-dot](https://github.com/dagrejs/graphlib-dot)
125127

128+
# Ideas
129+
* consider 3d interface such as [this button shadows example](https://lume.io/docs/#/examples/buttons-with-shadow)
126130

127131
# Development
128132
* Physics engine : Matter.js (looking for wasm accelerated replacement)

src/graph_io.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ return res;
2222
}
2323

2424
function select_label(obj){
25-
if(config.name_over_label){
25+
if(config.io.name_over_label){
2626
if(defined(obj.name)){
2727
obj.label = obj.name;
2828
}else if(defined(obj.properties)){

src/layout.js

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,51 @@ function neighbors_centrality(vertices,center){
5050
return neighbors
5151
}
5252

53+
function get_out_edges(edge){
54+
let res = []
55+
const outV_id = edge.outV.id
56+
for(let [eid,e] of Object.entries(edge.outV.edges)){
57+
if(e.inV.id == outV_id){
58+
res.push(e)
59+
}
60+
}
61+
return res
62+
}
63+
64+
function get_in_edges(edge){
65+
let res = []
66+
const inV_id = edge.inV.id
67+
for(let [eid,e] of Object.entries(edge.inV.edges)){
68+
if(e.outV.id == inV_id){
69+
res.push(e)
70+
}
71+
}
72+
return res
73+
}
74+
75+
function traverse_edges(g,edge,out_stream){
76+
for(let [eid,e] of Object.entries(g.edges)){
77+
e.seen = false
78+
}
79+
80+
let path_e = new Set()
81+
let todo_e = out_stream?get_out_edges(edge):get_in_edges(edge)
82+
while(todo_e.length > 0){
83+
let current_e = todo_e.shift()
84+
if(!current_e.seen){
85+
current_e.seen = true
86+
path_e.add(current_e)
87+
let add_e = out_stream?get_out_edges(current_e):get_in_edges(current_e)
88+
todo_e.push(...add_e)
89+
}
90+
}
91+
92+
for(let [eid,e] of Object.entries(g.edges)){
93+
delete e.seen
94+
}
95+
return path_e
96+
}
97+
5398
function remove_add_pinned(g,vertices,already_placed){
5499
for(let [vid,v] of Object.entries(g.vertices)){
55100
if(defined(v.pinned) && v.pinned){
@@ -179,6 +224,11 @@ class Layout{
179224
edges_visibility(g,true)
180225

181226
}
227+
traverse_edge_path(graph,edge){
228+
const set_up = traverse_edges(graph,edge,true)
229+
const set_down = traverse_edges(graph,edge,false)
230+
return new Set([...set_up, ...set_down])
231+
}
182232
}
183233

184234

src/mouse.js

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,12 @@ function onMousePan(e){
4747
if(["mousemove","touchmove"].includes(e.type)){
4848
//console.log(`dragging:${state.dragging} , over_vertex:${state.over_vertex}`)
4949
if(!state.dragging && !state.menu){//then no update for the hover state machine
50+
if(!is_edge){
51+
if(state.over_edge){
52+
event("edge_hover",{type:"exit",id:state.id})
53+
state.over_edge = false
54+
}
55+
}
5056
if(is_vertex){
5157
if(!state.over_vertex){
5258
state.id = e.target.id
@@ -81,11 +87,6 @@ function onMousePan(e){
8187
event("edge_hover",{type:"move",id:state.id,x:pointer_x,y:pointer_y})
8288
}
8389
}
84-
}else{
85-
if(state.over_edge){
86-
event("edge_hover",{type:"exit",id:state.id})
87-
state.over_edge = false
88-
}
8990
}
9091
}
9192
if(pointe_1 && state.dragging){

src/render.js

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,15 @@ import {Menu} from "./menu.js"
44
import {Edge} from "./render/edge_render.js"
55
import {Group} from "./render/group_render.js"
66

7+
import { Layout } from "./layout.js";
8+
9+
710
let utl = new Svg()
811
let menu = new Menu()
912
let edge = new Edge()
1013
let group = new Group()
14+
let layout = new Layout()
15+
1116

1217
let g = null;
1318
let svg = null;
@@ -129,8 +134,20 @@ function onVertexHover(e){
129134
}
130135
function onEdgeHover(e){
131136
const edge = g.edges[e.detail.id]
132-
if(e.detail.type != "move"){
133-
console.log(`hover over edge (${edge.outV.label},${edge.inV.label}) => ${e.detail.type}`)
137+
if(e.detail.type == "enter"){
138+
let path_edges_set = layout.traverse_edge_path(g,edge)
139+
edge.svg.path.classList.add("hover")
140+
for(let p_edge of path_edges_set){
141+
p_edge.svg.path.classList.add("hover")
142+
}
143+
console.log(`hover enter edge (${edge.outV.label} -> ${edge.inV.label})`)
144+
}else if(e.detail.type == "exit"){
145+
let path_edges_set = layout.traverse_edge_path(g,edge)
146+
edge.svg.path.classList.remove("hover")
147+
for(let p_edge of path_edges_set){
148+
p_edge.svg.path.classList.remove("hover")
149+
}
150+
console.log(`hover exit edge (${edge.outV.label} -> ${edge.inV.label})`)
134151
}
135152
}
136153

0 commit comments

Comments
 (0)