Better windows height & overflow + graflow autoplace at drawing
This commit is contained in:
@@ -13,6 +13,7 @@
|
|||||||
display: grid;
|
display: grid;
|
||||||
grid-gap: 5px;
|
grid-gap: 5px;
|
||||||
background:#888;
|
background:#888;
|
||||||
|
font-size: 16px;
|
||||||
}
|
}
|
||||||
.demooptions{
|
.demooptions{
|
||||||
padding: 2px;
|
padding: 2px;
|
||||||
@@ -20,9 +21,10 @@
|
|||||||
top: 2px;
|
top: 2px;
|
||||||
left: 2px;
|
left: 2px;
|
||||||
width: 10em;
|
width: 10em;
|
||||||
background: #CCC8;
|
background: #FFFB;
|
||||||
border-radius: 5px;
|
border-radius: 5px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
z-index:99;
|
||||||
}
|
}
|
||||||
.demooptions button{
|
.demooptions button{
|
||||||
text-transform: none;
|
text-transform: none;
|
||||||
@@ -33,7 +35,7 @@
|
|||||||
overflow: scroll;
|
overflow: scroll;
|
||||||
}
|
}
|
||||||
bz-graflow.compunet{ grid-column: 1 / -1; width: 80vw; height: 40vh; background:black; }
|
bz-graflow.compunet{ grid-column: 1 / -1; width: 80vw; height: 40vh; background:black; }
|
||||||
bz-graflow.eic{ grid-column: 1 / -1; width: 80vw; height: 40vh; background: var(--eicui-base-color-grey-10); }
|
bz-graflow.eic{ grid-column: 1 / -1; width: 80vw; height: 20vh; background: var(--eicui-base-color-grey-10); }
|
||||||
bz-graflow.organi{ width: 40vw; height: 100vh; background:black; }
|
bz-graflow.organi{ width: 40vw; height: 100vh; background:black; }
|
||||||
</style>
|
</style>
|
||||||
<script>
|
<script>
|
||||||
|
|||||||
@@ -4,7 +4,7 @@
|
|||||||
"nodes":[
|
"nodes":[
|
||||||
{ "nodeType": "eicBasic",
|
{ "nodeType": "eicBasic",
|
||||||
"id": "aze",
|
"id": "aze",
|
||||||
"coords": { "x": 50, "y": 120},
|
"ncoords": { "x": 50, "y": 120},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "Build attendees list",
|
"title": "Build attendees list",
|
||||||
"subtitle": "Build an attendees list to email"
|
"subtitle": "Build an attendees list to email"
|
||||||
@@ -13,7 +13,7 @@
|
|||||||
},
|
},
|
||||||
{ "nodeType": "eicBasic",
|
{ "nodeType": "eicBasic",
|
||||||
"id": "aze2",
|
"id": "aze2",
|
||||||
"coords": { "x": 100, "y": 220},
|
"ncoords": { "x": 100, "y": 220},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "Select message",
|
"title": "Select message",
|
||||||
"subtitle": "Select an email template"
|
"subtitle": "Select an email template"
|
||||||
@@ -22,7 +22,7 @@
|
|||||||
},
|
},
|
||||||
{ "nodeType": "eicBasic",
|
{ "nodeType": "eicBasic",
|
||||||
"id": "aze3",
|
"id": "aze3",
|
||||||
"coords": { "x": 150, "y": 320},
|
"ncoords": { "x": 150, "y": 320},
|
||||||
"markup": {
|
"markup": {
|
||||||
"title": "Data mapping",
|
"title": "Data mapping",
|
||||||
"subtitle": "Associate content variables with attendees data"
|
"subtitle": "Associate content variables with attendees data"
|
||||||
|
|||||||
@@ -102,6 +102,7 @@ menu[eicmenu] [menuitem] > a > button, menu[eicmenu] [menuitem] > .nolink button
|
|||||||
padding-left: var(--app-menu-expanded-width);
|
padding-left: var(--app-menu-expanded-width);
|
||||||
}
|
}
|
||||||
[eicapp] > [eicmenu][collapsed]:not(:hover) + .app-workspace{
|
[eicapp] > [eicmenu][collapsed]:not(:hover) + .app-workspace{
|
||||||
|
height: calc(100vh - var(--eicui-app-toolbar-height-active) - 0px);
|
||||||
padding-left: var(--app-menu-collapsed-width);
|
padding-left: var(--app-menu-collapsed-width);
|
||||||
}
|
}
|
||||||
[eicapp] .app-workspace .window {
|
[eicapp] .app-workspace .window {
|
||||||
@@ -173,7 +174,8 @@ menu[eicmenu] [menuitem] > a > button, menu[eicmenu] [menuitem] > .nolink button
|
|||||||
min-height: calc(100vh - var(--eicui-app-toolbar-height-active));
|
min-height: calc(100vh - var(--eicui-app-toolbar-height-active));
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
[eicapp] .app-workspace .window[expanded] > header h1 {
|
[eicapp] .app-workspace .window[expanded] > header h1,
|
||||||
|
[eicapp] .app-workspace .window:not([expanded]) > section > article > header{
|
||||||
display:none;
|
display:none;
|
||||||
}
|
}
|
||||||
[eicapp] .app-workspace .window[expanded] > header .controls {
|
[eicapp] .app-workspace .window[expanded] > header .controls {
|
||||||
@@ -278,7 +280,7 @@ menu[eicmenu] [menuitem] > a > button, menu[eicmenu] [menuitem] > .nolink button
|
|||||||
margin: 0;
|
margin: 0;
|
||||||
}
|
}
|
||||||
article[eiccard][media] > header {
|
article[eiccard][media] > header {
|
||||||
padding: var(--eicui-base-spacing-l) var(--eicui-base-spacing-m) var(--eicui-base-spacing-s) var(--eicui-base-spacing-m);
|
padding: var(--eicui-base-spacing-s) var(--eicui-base-spacing-m) 0 var(--eicui-base-spacing-m);
|
||||||
}
|
}
|
||||||
|
|
||||||
.eic-session {
|
.eic-session {
|
||||||
@@ -325,6 +327,7 @@ article[eiccard][media] > header {
|
|||||||
}
|
}
|
||||||
|
|
||||||
div.window > section:first-of-type > article[eiccard]:first-of-type{
|
div.window > section:first-of-type > article[eiccard]:first-of-type{
|
||||||
|
height:100%;
|
||||||
border: 2px solid var(--app-color-primary);
|
border: 2px solid var(--app-color-primary);
|
||||||
border-radius: .5rem;
|
border-radius: .5rem;
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+48
-7
@@ -104,8 +104,8 @@ class BZgraflow extends Buildoz{
|
|||||||
}
|
}
|
||||||
if(typeof(node.data)=='object') Object.assign(this.stagedNodes[id].dataset, node.data)
|
if(typeof(node.data)=='object') Object.assign(this.stagedNodes[id].dataset, node.data)
|
||||||
const portEls = this.stagedNodes[id].querySelectorAll('.port')
|
const portEls = this.stagedNodes[id].querySelectorAll('.port')
|
||||||
this.stagedNodes[id].style.left = `${node.coords.x}px`
|
this.stagedNodes[id].style.left = (node.coords && node.coords.x) ? `${node.coords.x}px` : '10%'
|
||||||
this.stagedNodes[id].style.top = `${node.coords.y}px`
|
this.stagedNodes[id].style.top = (node.coords && node.coords.y) ? `${node.coords.y}px` : '10%'
|
||||||
this.stagedNodes[id].dataset.id = id
|
this.stagedNodes[id].dataset.id = id
|
||||||
this.stagedNodes[id].ports = Object.fromEntries(Array.from(portEls).map(item => ([item.dataset.id, { ...item.dataset, el:item }])))
|
this.stagedNodes[id].ports = Object.fromEntries(Array.from(portEls).map(item => ([item.dataset.id, { ...item.dataset, el:item }])))
|
||||||
this.nodesContainer.append(this.stagedNodes[id])
|
this.nodesContainer.append(this.stagedNodes[id])
|
||||||
@@ -129,12 +129,21 @@ class BZgraflow extends Buildoz{
|
|||||||
}
|
}
|
||||||
|
|
||||||
refresh(){
|
refresh(){
|
||||||
|
let forceAutoplace = false
|
||||||
for(const node of this.flow.nodes){
|
for(const node of this.flow.nodes){
|
||||||
|
if((!node.coords) || (!node.coords.x) ||(!node.coords.y)) forceAutoplace=true
|
||||||
this.addNode(node)
|
this.addNode(node)
|
||||||
}
|
}
|
||||||
for(const link of this.flow.links){
|
for(const link of this.flow.links){
|
||||||
this.addWire(link)
|
this.addWire(link)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(forceAutoplace){
|
||||||
|
const bb=this.getBoundingClientRect()
|
||||||
|
//TODO compute tensions from nodes
|
||||||
|
if(bb.width > bb.height) this.autoPlace('horizontal', 80, 30, 500)
|
||||||
|
else this.autoPlace('vertical', 80, 30, 200)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bezier(idNode1, idPort1, idNode2, idPort2, tensionMin=60) {
|
bezier(idNode1, idPort1, idNode2, idPort2, tensionMin=60) {
|
||||||
@@ -171,7 +180,7 @@ class BZgraflow extends Buildoz{
|
|||||||
return `M ${x1} ${y1} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}`
|
return `M ${x1} ${y1} C ${c1x} ${c1y}, ${c2x} ${c2y}, ${x2} ${y2}`
|
||||||
}
|
}
|
||||||
|
|
||||||
autoPlace(orientation = 'horizontal', gapx = 80, gapy = 30){
|
autoPlace(orientation = 'horizontal', gapx = 80, gapy = 30, tween=1000){
|
||||||
if(this.hasAnyLoop(this.flow.nodes, this.flow.links)){
|
if(this.hasAnyLoop(this.flow.nodes, this.flow.links)){
|
||||||
console.warn('Loop(s) detected... Cannot auto-place !')
|
console.warn('Loop(s) detected... Cannot auto-place !')
|
||||||
return
|
return
|
||||||
@@ -219,7 +228,7 @@ class BZgraflow extends Buildoz{
|
|||||||
for(const nid of layer){
|
for(const nid of layer){
|
||||||
const bb = this.stagedNodes[nid].getBoundingClientRect()
|
const bb = this.stagedNodes[nid].getBoundingClientRect()
|
||||||
wMax = (bb.width > wMax) ? bb.width : wMax
|
wMax = (bb.width > wMax) ? bb.width : wMax
|
||||||
this.moveNode(nid, x, y, 1000)
|
this.moveNode(nid, x, y, tween)
|
||||||
y += gapy + bb.height
|
y += gapy + bb.height
|
||||||
}
|
}
|
||||||
x += wMax + gapx
|
x += wMax + gapx
|
||||||
@@ -232,7 +241,7 @@ class BZgraflow extends Buildoz{
|
|||||||
for(const nid of layer){
|
for(const nid of layer){
|
||||||
const bb = this.stagedNodes[nid].getBoundingClientRect()
|
const bb = this.stagedNodes[nid].getBoundingClientRect()
|
||||||
hMax = (bb.height > hMax) ? bb.width : hMax
|
hMax = (bb.height > hMax) ? bb.width : hMax
|
||||||
this.moveNode(nid, x, y, 1000)
|
this.moveNode(nid, x, y, tween)
|
||||||
x += gapx + bb.width
|
x += gapx + bb.width
|
||||||
}
|
}
|
||||||
y += hMax + gapy
|
y += hMax + gapy
|
||||||
@@ -271,13 +280,11 @@ class BZgraflow extends Buildoz{
|
|||||||
const parentbb = this.stagedNodes[nid].parentElement.getBoundingClientRect()
|
const parentbb = this.stagedNodes[nid].parentElement.getBoundingClientRect()
|
||||||
const x0=bb.x - parentbb.x
|
const x0=bb.x - parentbb.x
|
||||||
const y0 = bb.y - parentbb.y
|
const y0 = bb.y - parentbb.y
|
||||||
console.log('y0:', y0, bb)
|
|
||||||
function frame(t) {
|
function frame(t) {
|
||||||
const p = Math.min((t - t0) / duration, 1)
|
const p = Math.min((t - t0) / duration, 1)
|
||||||
const k = p * p * (3 - 2 * p) // smoothstep
|
const k = p * p * (3 - 2 * p) // smoothstep
|
||||||
const x = x0 + (destx - x0) * k
|
const x = x0 + (destx - x0) * k
|
||||||
const y = y0 + (desty - y0) * k
|
const y = y0 + (desty - y0) * k
|
||||||
|
|
||||||
this.stagedNodes[nid].style.left = `${x}px`
|
this.stagedNodes[nid].style.left = `${x}px`
|
||||||
this.stagedNodes[nid].style.top = `${y}px`
|
this.stagedNodes[nid].style.top = `${y}px`
|
||||||
this.updateWires(nid)
|
this.updateWires(nid)
|
||||||
@@ -354,6 +361,40 @@ class BZgraflow extends Buildoz{
|
|||||||
return(this.flow.nodes.map(n => n.id).some(dfs))
|
return(this.flow.nodes.map(n => n.id).some(dfs))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
getLoopingLinks(nodes, links) {
|
||||||
|
const linkIndexes = []
|
||||||
|
const adj = {};
|
||||||
|
this.flow.nodes.forEach(node => adj[node.id] = [])
|
||||||
|
for(let [idx, link] of this.flow.links.entries()){
|
||||||
|
if(link.from[0] == link.to[0]) linkIndexes.push(idx) //self loops
|
||||||
|
adj[link.from[0]].push([link.to[0], idx])
|
||||||
|
}
|
||||||
|
|
||||||
|
const visiting = new Set()
|
||||||
|
const visited = new Set()
|
||||||
|
const loops = new Set()
|
||||||
|
const dfs = (nid) => {
|
||||||
|
if(visiting.has(nid)) {
|
||||||
|
loops.push()
|
||||||
|
return(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
if(visited.has(nid)) return(false)
|
||||||
|
visiting.add(nid)
|
||||||
|
for(const m of adj[nid]) {
|
||||||
|
if(dfs(m)) {
|
||||||
|
return(true)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
visiting.delete(nid)
|
||||||
|
visited.add(nid)
|
||||||
|
return(false)
|
||||||
|
}
|
||||||
|
return(this.flow.nodes.map(n => n.id).some(dfs))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
Buildoz.define('graflow', BZgraflow)
|
Buildoz.define('graflow', BZgraflow)
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user