Skip to content

Commit

Permalink
moving towards dynamic layout
Browse files Browse the repository at this point in the history
  • Loading branch information
Kesanov committed Apr 28, 2019
1 parent f4154f9 commit 5cb0cea
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 58 deletions.
108 changes: 65 additions & 43 deletions src/graph.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ class GraphLayout
ranks: {}
nodes: {}
edges: {}
reach: {}
graph: null

constructor: (@ranks = {}, @nodes = {}, @edges = {}) ->
Expand All @@ -105,15 +106,20 @@ class GraphLayout
for n, _ of newnodes
graph.addNode n
@graph.addNode n
for i, e of newedges
graph.addEdge e[0], e[1]
@edges[i] = e
for i, [s, t, o] of newedges when s != t
graph.addNode s if s not of newnodes
graph.addNode t if t not of newnodes
graph.addEdge s, t
@edges[i] = [s, t, o]
# INIT RANKS
for n, _ of newnodes
rank = 0
for t from graph.adges n when rank >= @ranks[t]
rank = @ranks[t]-1
@ranks[n] = rank if rank > 0
for t from graph.adges n
if rank >= @ranks[t]
rank = @ranks[t]-1
@ranks[n] = rank if rank < 0
if 0 not of @graph.edges
new Error('Graph must containt node with id = 0!')
@ranks[0] = 0
# ADD RANKS
queue = new UniqueQueue Queue, ([n, @ranks[n], n] for n, _ of newnodes when n of @ranks)
Expand All @@ -123,49 +129,56 @@ class GraphLayout
if n != t and (t not of @ranks or r == @ranks[t])
queue.insert t, r-1, t
# ORIENT EDGES
for e, [s,t,o] of newedges
for e, [s,t,o] of newedges when s != t
[s,t] = [t,s] if @ranks[s] < @ranks[t]
@graph.addEdge s, t
@edges[e] = [s,t,o]
for n, _ of @ranks
sort @graph.edges[n], (a) => @graph.rdges[a].length
sort @graph.rdges[n], (a) => @graph.rdges[a].length

sort @graph.edges[n], (a) => @graph.rdges[a].length + 1/a
sort @graph.rdges[n], (a) => @graph.rdges[a].length + 1/a
# ADD NODES
for i, _ of newnodes
@nodes[i] = [null, null]
# INIT REACH (PARALLEL PATHS)

# ADD REACH


# console.log ([n, @ranks[n]] for n,_ of newnodes)
layout: () =>
[xs, ys, x, y] = [[], [], 0, 0]
# PRELIMINARY
[remains, xs, ys, x, y] = [[], [], [], 0, 0]
queue = new UniqueQueue Stack, ([n, 1, 1] for n, r of @ranks when r == 0)
console.log @ranks, queue.queue.stack
for n, _ of @nodes
remains[n] = @graph.rdges[n].length
for [n, _, _] from queue.iter()
@nodes[n][1] = x++
xs.push n
console.log n, @graph.edges[n]
for t from @graph.edges[n]
queue.insert t, 1, 1 if @graph.rdges[t][0] == parseInt(n)
queue.insert t, 1, 1 if --remains[t] == 0
queue = new UniqueQueue Stack, ([n, 1, 1] for n, r of @ranks when r == 0)
queue.queue.stack = queue.queue.stack.reverse()
for n, _ of @nodes
remains[n] = @graph.rdges[n].length
for [n, _, _] from queue.iter()
@nodes[n][0] = y++
ys.push n
for t from @graph.edges[n].reverse()
queue.insert t, 1, 1 if last(@graph.rdges[t]) == parseInt(n)
[x, y] = [0, 0]
nx = {}
@nodes[xs[0]][1] = 0
@nodes[ys[0]][0] = 0
for i in [0..xs.length-2]
x++ if @nodes[xs[i]][0] > @nodes[xs[i+1]][0] or @graph.edges[xs[i]] == 1 and @graph.rdges[xs[i+1]] == 1
nx[xs[i+1]] = x
for i in [0..ys.length-2]
y++ if @nodes[ys[i]][1] > @nodes[ys[i+1]][1] or @graph.edges[ys[i]] == 1 and @graph.rdges[ys[i+1]] == 1
@nodes[ys[i+1]][0] = y
for n, x of nx
@nodes[n][1] = x
queue.insert t, 1, 1 if --remains[t] == 0

# COMPACTION
for n, pos of @nodes
pos[1] = pos[1] - pos[0]
pos[0] = pos[1] + pos[0] * 2
# pos[1] = pos[1] - pos[0]
pos[0] = @ranks[n] #pos[1] + pos[0] * 2
# [x, xs] = [0, sort (n for n,[_,x] of @nodes when x <= 0), (n) => -@nodes[n][1]]
# for i in [0..xs.length-2]
# @nodes[xs[i+1]][1] = if int(xs[i+1]) in @graph.edges[xs[i]] then x else --x
ns = sort (n for n,[_,x] of @nodes when x > 0), (n) => @nodes[n][1]
xs = (-1 for _ of @nodes)
for n in ns
@nodes[n][1] = xs[-@ranks[n]] = Math.max xs[-@ranks[n]-1], xs[-@ranks[n]]+1

class State

Expand All @@ -179,17 +192,25 @@ class State
for transition from @input
for n in transition.remove.nodes
delete @graph.nodes[n]
delete @graph.ranks[n]
delete @graph.graph.edges[n]
delete @graph.graph.rdges[n]
for e in transition.remove.edges
[s, t] = @graph.edges[e]
if s of @graph.nodes
@graph.graph.edges[s] = @graph.graph.edges[s].filter (x) => x != t
if t of @graph.nodes
@graph.graph.rdges[t] = @graph.graph.rdges[t].filter (x) => x != s
delete @graph.edges[e]

@graph.step transition.insert.nodes, transition.insert.edges
yield @graph

int = parseInt

readCSV = (fileNodes, fileEdges) ->
nodes = ((s.replace(/\s+/g, '') for s in line.split(',')) for line in fs.readFileSync(fileNodes, 'utf8').split('\n'))
edges = ((s.replace(/\s+/g, '') for s in line.split(',')) for line in fs.readFileSync(fileEdges, 'utf8').split('\n'))
readCSV = (file) ->
nodes = ((s.replace(/\s+/g, '') for s in line.split(',')) for line in fs.readFileSync(file+'/nodes.csv', 'utf8').split('\n'))
edges = ((s.replace(/\s+/g, '') for s in line.split(',')) for line in fs.readFileSync(file+'/edges.csv', 'utf8').split('\n'))
[n, e] = [1, 1]
while nodes[n++][0] != 'END' and edges[e++][0] != 'END'
t = {remove: {nodes: [], edges: []}, insert: {nodes: {}, edges: {}}}
Expand All @@ -205,19 +226,20 @@ readCSV = (fileNodes, fileEdges) ->
e++
yield t

state = new State readCSV '../data/nodes.csv', '../data/edges.csv'

state = new State readCSV '../data/27f'

i=0
for graph from state.iter()
graph.nodes[n][0] = r for n, r of graph.ranks
graph.layout()

file = fs.openSync('./layoutdata.coffee', 'w')
fs.writeSync(file, "export graph =\n")
fs.writeSync(file, " nodes:\n")
fs.writeSync(file, " " + n + " : [" + d + "]\n") for n, d of graph.nodes
fs.writeSync(file, " edges:\n")
fs.writeSync(file, " " + e + " : [" + d + "]\n") for e, d of graph.edges
fs.closeSync(file)
break
if i++ == 3
graph.nodes[n][0] = r for n, r of graph.ranks
graph.layout()

file = fs.openSync('./layoutdata.coffee', 'w')
fs.writeSync(file, "export graph =\n")
fs.writeSync(file, " nodes:\n")
fs.writeSync(file, " " + n + " : [" + d + "]\n") for n, d of graph.nodes
fs.writeSync(file, " edges:\n")
fs.writeSync(file, " " + e + " : [" + d + "]\n") for e, d of graph.edges
fs.closeSync(file)
break

37 changes: 22 additions & 15 deletions src/main.coffee
Original file line number Diff line number Diff line change
Expand Up @@ -7,21 +7,13 @@ import {graph} from 'layoutdata'

G = 15

scene = basegl.scene
domElement: 'scene'
width: 2048
height: 2048


eventReactor = new KeyboardMouseReactor scene

addNode = (n, [y, x]) ->
r = G/6
# name = basegl.text {str: "HELLO", scene: scene, fontFamily: 'SourceCodePro', size: 16}
node = scene.add basegl.symbol basegl.expr -> circle(r).move(r, r)
node.bbox.xy = [2*r, 2*r]
node.position.xy = [G*x, G*y]
node.addEventListener "mouseover", (e) -> console.log "OVER NODE!"
node.addEventListener "mouseover", (e) => alert "Node: " + n
group [node]

addEdge = ([ys, xs], [yt, xt], offset) ->
Expand Down Expand Up @@ -49,9 +41,24 @@ addLine = ([ys, xs], [yt, xt]) ->
line


for _, pos of graph.nodes
pos[1] += 50
for n, pos of graph.nodes
addNode n, pos
for _, [s, t, offset] of graph.edges
addLine graph.nodes[s], graph.nodes[t]
main = () ->
basegl.fontManager.register 'SourceCodePro', 'fonts/SourceCodePro.ttf'
await basegl.fontManager.load 'SourceCodePro'

eventReactor = new KeyboardMouseReactor scene

for _, pos of graph.nodes
pos[1] += 50
pos[0] += 60
for _, [s, t, offset] of graph.edges
addLine graph.nodes[s], graph.nodes[t]
for n, pos of graph.nodes
addNode n, pos


scene = basegl.scene
domElement: 'scene'
width: 2048
height: 2048

main()

0 comments on commit 5cb0cea

Please sign in to comment.