diff --git a/bzGraflow.js b/bzGraflow.js index b33016e..f3a6c50 100644 --- a/bzGraflow.js +++ b/bzGraflow.js @@ -1195,15 +1195,45 @@ class BZgraflow extends Buildoz{ } autofit(percent=100){ + if(!this.parentElement) return + + const prevTransformOrigin = this.style.transformOrigin + this.style.transform = 'none' + this.style.transformOrigin = 'top left' + + // Measure real content by unioning viewport-space bounding boxes. + // This is robust with overflow:auto and absolute-positioned layers. + let left = Infinity + let top = Infinity + let right = -Infinity + let bottom = -Infinity + + const includeBB = (bb) => { + if(!bb) return + left = Math.min(left, bb.left) + top = Math.min(top, bb.top) + right = Math.max(right, bb.right) + bottom = Math.max(bottom, bb.bottom) + } + + this.nodesContainer?.querySelectorAll?.('.bzgf-node').forEach(nodeEl => includeBB(nodeEl.getBoundingClientRect())) + this.wiresContainer?.querySelectorAll?.('path.bzgf-wire').forEach(path => includeBB(path.getBoundingClientRect())) + const parentBB = this.parentElement.getBoundingClientRect() - // Use scroll dimensions for actual content extent (nodes can extend beyond element bounds) - const contentW = Math.max(this.scrollWidth || this.offsetWidth || 1, 1) - const contentH = Math.max(this.scrollHeight || this.offsetHeight || 1, 1) + const gapx = parseInt(this.getBZAttribute('gapx')) || 80 + const gapy = parseInt(this.getBZAttribute('gapy')) || 80 + const rawW = Number.isFinite(left) && Number.isFinite(right) ? Math.max(right - left, 1) : Math.max(this.mainContainer?.clientWidth || this.offsetWidth || 1, 1) + const rawH = Number.isFinite(top) && Number.isFinite(bottom) ? Math.max(bottom - top, 1) : Math.max(this.mainContainer?.clientHeight || this.offsetHeight || 1, 1) + const contentW = rawW + (2 * gapx) + const contentH = rawH + (2 * gapy) const sx = parentBB.width / contentW const sy = parentBB.height / contentH const scale = Math.min(sx, sy)*(percent/100) // uniform scale to fit inside parent - this.style.transformOrigin = 'top left' - this.style.transform = `scale(${scale})` + const tx = Number.isFinite(left) ? (-left + gapx) : gapx + const ty = Number.isFinite(top) ? (-top + gapy) : gapy + this.style.transformOrigin = prevTransformOrigin || 'top left' + // First normalize content origin to (0,0), then scale to fit. + this.style.transform = `scale(${scale}) translate(${tx}px, ${ty}px)` } } Buildoz.define('graflow', BZgraflow) diff --git a/graflow_examples/test4.html b/graflow_examples/test4.html index 0d88e88..d1fc467 100644 --- a/graflow_examples/test4.html +++ b/graflow_examples/test4.html @@ -110,7 +110,7 @@ ro.observe(el) let aifmi = null; let sidx=0; - const sevanimation = () => { console.log('sevanimation') + const sevanimation = () => { severities.forEach(severity => aifmi.removeAttribute(severity)) aifmi.setAttribute(severities[sidx], '') sidx++