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