graflow: port heights used in layer reordering
This commit is contained in:
52
bzGraflow.js
52
bzGraflow.js
@@ -59,11 +59,6 @@ class BZgraflow extends Buildoz{
|
||||
}
|
||||
await this.loadNodes(flowObj.nodesFile)
|
||||
this.flow = flowObj.flow
|
||||
|
||||
if(this.hasAnyLoop()) {
|
||||
console.warn('This flow has loops.Optimization not available')
|
||||
console.log('===Loops:===>', this.getLoopingLinks())
|
||||
}
|
||||
this.refresh()
|
||||
}
|
||||
|
||||
@@ -198,7 +193,6 @@ class BZgraflow extends Buildoz{
|
||||
if(this.hasAnyLoop(this.flow.nodes, this.flow.links)){
|
||||
console.warn('Loop(s) detected... Cannot auto-place !')
|
||||
const backEdges = this.findBackEdges(this.flow.nodes, this.flow.links)
|
||||
console.log('===BackEdges:===>', backEdges)
|
||||
linksWithoutBackEdges = this.flow.links.filter((link, idx) => (!backEdges.includes(idx)) && (link.from[0] != link.to[0]))
|
||||
} else {
|
||||
linksWithoutBackEdges = this.flow.links
|
||||
@@ -221,14 +215,14 @@ class BZgraflow extends Buildoz{
|
||||
const layers = this.computeLayers(this.flow.nodes, parents)
|
||||
let maxHeight = 0; let maxWidth = 0
|
||||
const layerHeights = []; const layerWidths = [];
|
||||
const indexes = {} // Todo: a
|
||||
const indexes = {} // indexes[nid] = { base: <int>, ports: { [portId]: <float in [0,1)> } }
|
||||
for(const layer of layers){
|
||||
let totHeight = 0; let totWidth = 0
|
||||
for(const [idx, nid] of layer.entries()){
|
||||
const bb = this.stagedNodes[nid].getBoundingClientRect()
|
||||
totHeight += bb.height + gapy
|
||||
totWidth += bb.width + gapx
|
||||
indexes[nid] = idx
|
||||
indexes[nid] = { base: idx, ports: this.computePortOffsets(nid, orientation) }
|
||||
}
|
||||
if(totHeight>maxHeight) maxHeight = totHeight
|
||||
layerHeights.push(totHeight)
|
||||
@@ -236,7 +230,7 @@ class BZgraflow extends Buildoz{
|
||||
layerWidths.push(totWidth)
|
||||
}
|
||||
|
||||
this.reorderLayers(layers, parents, indexes)
|
||||
this.reorderLayers(layers, parents, indexes, orientation)
|
||||
|
||||
if(orientation=='horizontal'){
|
||||
let x = gapx
|
||||
@@ -263,17 +257,45 @@ class BZgraflow extends Buildoz{
|
||||
x += gapx + bb.width
|
||||
}
|
||||
y += hMax + gapy
|
||||
console.log(y, hMax, gapy )
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
reorderLayers(layers, parents, indexes){
|
||||
computePortOffsets(nid, orientation = 'horizontal'){
|
||||
const node = this.stagedNodes[nid]
|
||||
if(!node || !node.ports) return({})
|
||||
const axis = (orientation === 'vertical') ? 'x' : 'y'
|
||||
const nodeRect = node.getBoundingClientRect()
|
||||
const ports = Object.entries(node.ports)
|
||||
.map(([pid, p]) => {
|
||||
const r = p.el.getBoundingClientRect()
|
||||
const pos = (axis === 'x')
|
||||
? (r.left + (r.width / 2) - nodeRect.left)
|
||||
: (r.top + (r.height / 2) - nodeRect.top)
|
||||
return({ pid, pos })
|
||||
})
|
||||
.sort((a, b) => a.pos - b.pos) // smaller pos => "higher/left" => smaller offset
|
||||
|
||||
const denom = ports.length + 1
|
||||
const offsets = {}
|
||||
for(const [rank, item] of ports.entries()){
|
||||
offsets[item.pid] = rank / denom // always < 1
|
||||
}
|
||||
return(offsets)
|
||||
}
|
||||
|
||||
reorderLayers(layers, parents, indexes, orientation = 'horizontal'){
|
||||
const swap = (vect, todo) => {
|
||||
for(const s of todo){
|
||||
[vect[s[0]], vect[s[1]]] = [vect[s[1]], vect[s[0]]]
|
||||
}
|
||||
}
|
||||
const adjIndex = (nid, portId) => {
|
||||
const info = indexes?.[nid]
|
||||
const base = (info && info.base !== undefined) ? info.base : 0
|
||||
const off = (portId && info?.ports?.[portId] !== undefined) ? info.ports[portId] : 0
|
||||
return(base + off)
|
||||
}
|
||||
for(const [lidx, layer] of layers.entries()){
|
||||
if(lidx==0) continue
|
||||
const toSwap = []
|
||||
@@ -284,7 +306,13 @@ class BZgraflow extends Buildoz{
|
||||
for(let j=i+1; j<layer.length; j++){
|
||||
const nid2 = layer[j]
|
||||
const pnid2 = parents[nid2].find((nid => layers[lidx-1].includes(nid)))
|
||||
if(((indexes[pnid1] - indexes[pnid2]) * (indexes[nid1] - indexes[nid2])) < 0) { // crossing !
|
||||
const link1 = (pnid1) ? this.getLink(pnid1, nid1) : null
|
||||
const link2 = (pnid2) ? this.getLink(pnid2, nid2) : null
|
||||
const p1 = adjIndex(pnid1, link1?.from?.[1])
|
||||
const p2 = adjIndex(pnid2, link2?.from?.[1])
|
||||
const c1 = adjIndex(nid1, link1?.to?.[1])
|
||||
const c2 = adjIndex(nid2, link2?.to?.[1])
|
||||
if(((p1 - p2) * (c1 - c2)) < 0) { // crossing (now refined by per-port ordering)
|
||||
toSwap.push([i, j])
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user