graflow: wireType straight
This commit is contained in:
114
bzGraflow.js
114
bzGraflow.js
@@ -85,10 +85,11 @@ class BZgraflow extends Buildoz{
|
||||
this.mainContainer.append(this.nodesContainer)
|
||||
this.append(this.hostContainer)
|
||||
this.loadFlow(flowUrl).then(() => {
|
||||
if(this.hasAttribute('editable')){
|
||||
if((this.getBZAttribute('edit')=='move') || (this.getBZAttribute('edit')=='full')){
|
||||
this.dnd = new MovingNodes(this)
|
||||
this.dnd.enableMovingNodes('.bzgf-node') }
|
||||
}) // Let it load async
|
||||
this.dnd.enableMovingNodes('.bzgf-node')
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
error(msg, err){
|
||||
@@ -393,7 +394,7 @@ class BZgraflow extends Buildoz{
|
||||
addWire(link){
|
||||
const [idNode1, idPort1] = link.from
|
||||
const [idNode2, idPort2] = link.to
|
||||
const path = this.bezierNodes(idNode1, idPort1, idNode2, idPort2, this.getBZAttribute('tension'))
|
||||
const path = this.linkNodes(idNode1, idPort1, idNode2, idPort2)
|
||||
const id = `${idNode1}_${idNode2}`
|
||||
this.stagedWires[id] = document.createElementNS('http://www.w3.org/2000/svg', 'path')
|
||||
this.stagedWires[id].setAttribute('d', path)
|
||||
@@ -458,8 +459,9 @@ class BZgraflow extends Buildoz{
|
||||
return({ x: x - r.left, y: y - r.top })
|
||||
}
|
||||
|
||||
bezierNodes(idNode1, idPort1, idNode2, idPort2, tension=60) {
|
||||
tension = parseInt(tension)
|
||||
linkNodes(idNode1, idPort1, idNode2, idPort2) {
|
||||
const tension = parseInt(this.getBZAttribute('tension')) || 60
|
||||
const wireType = this.getBZAttribute('wiretype') || 'bezier'
|
||||
const node1 = this.stagedNodes[idNode1]
|
||||
const port1 = node1.ports[idPort1]
|
||||
const node2 = this.stagedNodes[idNode2]
|
||||
@@ -477,7 +479,6 @@ class BZgraflow extends Buildoz{
|
||||
const x2 = Math.floor(p2.x)
|
||||
const y2 = Math.floor(p2.y)
|
||||
const loop = (idNode1==idNode2) && (idPort1==idPort2)
|
||||
const dist = Math.abs(x2 - x1) + Math.abs(y2 - y1)
|
||||
|
||||
let c1x = Math.floor(x1 + (this.dirVect[port1.direction].x * tension))
|
||||
let c1y = Math.floor(y1 + (this.dirVect[port1.direction].y * tension))
|
||||
@@ -493,41 +494,68 @@ class BZgraflow extends Buildoz{
|
||||
c2y -= 1*tension
|
||||
}
|
||||
}
|
||||
|
||||
if(wireType === 'bezier') {
|
||||
return(`M ${x1} ${y1} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}`)
|
||||
}
|
||||
if(wireType === 'straight') {
|
||||
console.log('straight')
|
||||
// Straight segments through the same control points
|
||||
return(`M ${x1} ${y1} L ${c1x} ${c1y} L ${c2x} ${c2y} L ${x2} ${y2}`)
|
||||
}
|
||||
return('')
|
||||
//return(`M ${x1} ${y1} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}`)
|
||||
}
|
||||
|
||||
bezierInterNodes(idNode1, idPort1, idNode2, idPort2, interNodes, orientation='horizontal', tension=60) {
|
||||
tension = parseInt(tension)
|
||||
linkInterNodes(idNode1, idPort1, idNode2, idPort2, interNodes, orientation='horizontal') {
|
||||
const tension = parseInt(this.getBZAttribute('tension')) || 60
|
||||
const wireType = this.getBZAttribute('wiretype') || 'bezier'
|
||||
const node1 = this.stagedNodes[idNode1]
|
||||
let port1 = node1.ports[idPort1]
|
||||
|
||||
const makeCubicBezier = (x1, y1, x2, y2, orientation1, orientation2) => {
|
||||
const dist = Math.abs(x2 - x1) + Math.abs(y2 - y1)
|
||||
const port1 = node1.ports[idPort1]
|
||||
const node2 = this.stagedNodes[idNode2]
|
||||
const port2 = node2.ports[idPort2]
|
||||
if(!node1 || !node2 || !port1 || !port2) {
|
||||
console.warn('Link on bad node / port ', idNode1, idPort1, idNode2, idPort2)
|
||||
return('')
|
||||
}
|
||||
|
||||
const makeSegment = (x1, y1, x2, y2, orientation1, orientation2) => {
|
||||
let c1x, c1y, c2x, c2y
|
||||
if(orientation1=='horizontal'){
|
||||
if(orientation1=='horizontal') {
|
||||
c1x = Math.floor(x1 + tension)
|
||||
c1y = y1
|
||||
} else {
|
||||
c1x = x1
|
||||
c1y = Math.floor(y1 + tension)
|
||||
}
|
||||
if(orientation2=='horizontal'){
|
||||
if(orientation2=='horizontal') {
|
||||
c2x = Math.floor(x2 - tension)
|
||||
c2y = y2
|
||||
} else {
|
||||
c2x = x2
|
||||
c2y = Math.floor(y2 - tension)
|
||||
}
|
||||
if(wireType === 'bezier') {
|
||||
return(`C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}`)
|
||||
}
|
||||
const directPath = this.bezierNodes(idNode1, idPort1, idNode2, idPort2, tension)
|
||||
const startPath = directPath.substring(0,directPath.indexOf('C'))
|
||||
const endPath = directPath.substring(directPath.lastIndexOf(',')+1).trim()
|
||||
let path = startPath
|
||||
let [ , x1, y1] = startPath.split(' ')
|
||||
x1 = parseFloat(x1)
|
||||
y1 = parseFloat(y1)
|
||||
if(wireType === 'straight') {
|
||||
return(`L ${c1x} ${c1y} L ${c2x} ${c2y} L ${x2} ${y2}`)
|
||||
}
|
||||
return(`C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}`)
|
||||
}
|
||||
|
||||
// Start/end points in SVG coords (works for both bezier and line)
|
||||
const bb1 = port1.el.getBoundingClientRect()
|
||||
const bb2 = port2.el.getBoundingClientRect()
|
||||
const sp = this.clientToSvg(bb1.x + (bb1.width/2), bb1.y + (bb1.height/2))
|
||||
const ep = this.clientToSvg(bb2.x + (bb2.width/2), bb2.y + (bb2.height/2))
|
||||
let x1 = Math.floor(sp.x)
|
||||
let y1 = Math.floor(sp.y)
|
||||
const xEnd = Math.floor(ep.x)
|
||||
const yEnd = Math.floor(ep.y)
|
||||
let path = `M ${x1} ${y1} `
|
||||
|
||||
let firstPort = port1
|
||||
for(const interNode of interNodes){
|
||||
const bb = this.stagedNodes[interNode].getBoundingClientRect()
|
||||
// Entry/exit points on the placeholder box, converted to SVG coords (handles CSS transforms)
|
||||
@@ -544,11 +572,11 @@ class BZgraflow extends Buildoz{
|
||||
let x2 = Math.floor(entry.x)
|
||||
let y2 = Math.floor(entry.y)
|
||||
|
||||
if(port1){
|
||||
path += makeCubicBezier(x1, y1, x2, y2, ['w','e'].includes(port1.direction) ? 'horizontal' : 'vertical', orientation)
|
||||
port1 = false
|
||||
if(firstPort){
|
||||
path += makeSegment(x1, y1, x2, y2, ['w','e'].includes(firstPort.direction) ? 'horizontal' : 'vertical', orientation)
|
||||
firstPort = null
|
||||
} else {
|
||||
path += makeCubicBezier(x1, y1, x2, y2, orientation, orientation)
|
||||
path += makeSegment(x1, y1, x2, y2, orientation, orientation)
|
||||
}
|
||||
|
||||
const x3 = Math.floor(exit.x)
|
||||
@@ -558,10 +586,7 @@ class BZgraflow extends Buildoz{
|
||||
x1 = x3
|
||||
y1 = y3
|
||||
}
|
||||
let [x2, y2] = endPath.split(' ')
|
||||
x2 = parseFloat(x2)
|
||||
y2 = parseFloat(y2)
|
||||
path += ' '+makeCubicBezier(x1, y1, x2, y2, orientation, orientation)
|
||||
path += ' ' + makeSegment(x1, y1, xEnd, yEnd, orientation, orientation)
|
||||
return(path)
|
||||
}
|
||||
|
||||
@@ -574,12 +599,7 @@ class BZgraflow extends Buildoz{
|
||||
|
||||
// Cleanup placeholders from previous autoPlace() runs.
|
||||
// Each run creates new longLinkPlaceHolder_* IDs; without cleanup they accumulate in the DOM.
|
||||
for(const nid of Object.keys(this.stagedNodes || {})){
|
||||
if(!nid.startsWith('longLinkPlaceHolder_')) continue
|
||||
const el = this.stagedNodes[nid]
|
||||
if(el?.parentNode) el.parentNode.removeChild(el)
|
||||
delete this.stagedNodes[nid]
|
||||
}
|
||||
this.clearFakeNodes()
|
||||
|
||||
// Loops create infinite recursion in dfs for getting parents & adjacency lists: Remove them !
|
||||
let linksWithoutBackEdges
|
||||
@@ -724,6 +744,15 @@ class BZgraflow extends Buildoz{
|
||||
}
|
||||
}
|
||||
|
||||
clearFakeNodes(){
|
||||
for(const nid of Object.keys(this.stagedNodes || {})){
|
||||
if(!nid.startsWith('longLinkPlaceHolder_')) continue
|
||||
const el = this.stagedNodes[nid]
|
||||
if(el?.parentNode) el.parentNode.removeChild(el)
|
||||
delete this.stagedNodes[nid]
|
||||
}
|
||||
}
|
||||
|
||||
getMaxWidth(layer){
|
||||
return(layer.filter(nid =>
|
||||
!nid.startsWith('longLinkPlaceHolder_'))
|
||||
@@ -849,7 +878,7 @@ class BZgraflow extends Buildoz{
|
||||
const y = y0 + (desty - y0) * k
|
||||
el.style.left = `${x}px`
|
||||
el.style.top = `${y}px`
|
||||
this.updateWires(nid, orientation)
|
||||
this.updateWires(nid, orientation, true)
|
||||
|
||||
if(p < 1) requestAnimationFrame(frame.bind(this))
|
||||
else{
|
||||
@@ -863,7 +892,7 @@ class BZgraflow extends Buildoz{
|
||||
requestAnimationFrame(frame.bind(this))
|
||||
}
|
||||
|
||||
updateWires(nid, orientation){
|
||||
updateWires(nid, orientation, LondLinkfix = false){
|
||||
const wires = Object.keys(this.stagedWires)
|
||||
.filter(id => (id.startsWith(nid+'_')||id.endsWith('_'+nid)))
|
||||
.map(id => this.stagedWires[id])
|
||||
@@ -873,11 +902,11 @@ class BZgraflow extends Buildoz{
|
||||
if(!lnk) continue
|
||||
if(!this.flow?.longLinks) this.flow.longLinks = []
|
||||
const longLink = this.flow.longLinks.find(item => (item.link.from[0] == lnk.from[0] && item.link.from[1] == lnk.from[1] && item.link.to[0] == lnk.to[0] && item.link.to[1] == lnk.to[1]))
|
||||
if(longLink) {
|
||||
const path = this.bezierInterNodes(nid1, lnk.from[1], nid2, lnk.to[1], longLink.interNodes, orientation, this.getBZAttribute('tension'))
|
||||
if(longLink && LondLinkfix) {
|
||||
const path = this.linkInterNodes(nid1, lnk.from[1], nid2, lnk.to[1], longLink.interNodes, orientation)
|
||||
wire.setAttribute('d', path)
|
||||
} else {
|
||||
const path = this.bezierNodes(nid1, lnk.from[1], nid2, lnk.to[1], this.getBZAttribute('tension'))
|
||||
const path = this.linkNodes(nid1, lnk.from[1], nid2, lnk.to[1])
|
||||
wire.setAttribute('d', path)
|
||||
}
|
||||
}
|
||||
@@ -1051,6 +1080,7 @@ class MovingNodes{
|
||||
}
|
||||
|
||||
pointerDown(e){
|
||||
this.graflow.clearFakeNodes()
|
||||
const node = (e.target.classList.contains(this.itemSelector)) ? e.target : e.target.closest(this.itemSelector)
|
||||
const handle = (node.classList.contains(this.handleSelector)) ? node : node.querySelector(this.handleSelector)
|
||||
|
||||
@@ -1081,7 +1111,7 @@ class MovingNodes{
|
||||
const y = e.clientY - startY + offsetY
|
||||
node.style.left = `${x}px`
|
||||
node.style.top = `${y}px`
|
||||
this.graflow.updateWires(node.dataset.id, this.graflow.currentOrientation)
|
||||
this.graflow.updateWires(node.dataset.id, this.graflow.currentOrientation, false)
|
||||
}
|
||||
|
||||
pointerUp(e){
|
||||
|
||||
Reference in New Issue
Block a user