{{breadcrumbs}}
HUB / lib_bejson_diagram_html.py
lib_bejson_diagram_html.py
- Runtime
- Python
- Category
- HTML
- Path
- /storage/emulated/0/Projects/Management/Libraries/py/HTML/lib_bejson_diagram_html.py
FILE // lib_bejson_diagram_html.py
"""
Library: lib_bejson_diagram_html.py
MFDB Version: 1.3.1
Format_Creator: Elton Boehnen
Status: OFFICIAL - v1.3.1
Date: 2026-05-06
"""
"""
Library: lib_bejson_diagram_html.py
Family: HTML
Version: 1.3 OFFICIAL
Description: Advanced HTML/SVG rendering engine for BEJSON 104db diagrams.
Features: GLOW filters, animated flows, and custom CSS theme support.
"""
import json
import os
from datetime import datetime
CYBERPUNK_TEMPLATE = """<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{TITLE}} · BEJSON 104db</title>
<link rel="preconnect" href="https://fonts.googleapis.com">
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=JetBrains+Mono:wght@300;400;700&display=swap" rel="stylesheet">
{{EXTERNAL_CSS}}
<style>
{{INTERNAL_CSS}}
</style>
</head>
<body>
<div class="page">
<header class="title-bar">
<div class="title-left">
<span class="schema-tag">BEJSON · 104db · {{MODE}} VIEW</span>
<h1>{{TITLE}}</h1>
<p class="subtitle">{{SUBTITLE}}</p>
</div>
</header>
<div class="diagram-wrapper">
<svg id="diagram-svg" viewBox="0 0 1440 720" preserveAspectRatio="xMidYMid meet">
<defs>
<pattern id="dots" x="0" y="0" width="32" height="32" patternUnits="userSpaceOnUse">
<circle cx="1" cy="1" r="1" fill="rgba(30,80,160,0.25)"/>
</pattern>
<filter id="glow-primary" x="-60%" y="-60%" width="220%" height="220%">
<feGaussianBlur stdDeviation="5" result="blur"/>
<feFlood flood-color="{{ACCENT_COLOR}}" flood-opacity="0.5" result="c"/>
<feComposite in="c" in2="blur" operator="in" result="shadow"/>
<feMerge><feMergeNode in="shadow"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
<filter id="line-glow" x="-30%" y="-200%" width="160%" height="500%">
<feGaussianBlur stdDeviation="2" result="blur"/>
<feMerge><feMergeNode in="blur"/><feMergeNode in="SourceGraphic"/></feMerge>
</filter>
</defs>
<rect width="100%" height="100%" fill="{{BG_COLOR}}"/>
<rect width="100%" height="100%" fill="url(#dots)"/>
<g id="connectors-layer"></g>
<g id="nodes-layer"></g>
</svg>
<div id="tooltip" class="hidden">
<div class="tt-title" id="tt-title"></div>
<div id="tt-body"></div>
</div>
</div>
<footer class="meta-bar">
<span>Format: BEJSON</span>
<span>Version: 104db</span>
<span>Exported: {{TIMESTAMP}}</span>
</footer>
</div>
<script id="bejson-data" type="application/json">
{{DIAGRAM_DATA}}
</script>
<script>
/* ── Renderer ────────────────────────────────────────────────────────── */
const THEME = {
accent: "{{ACCENT_COLOR}}",
bg: "{{BG_COLOR}}"
};
function render() {
const dataEl = document.getElementById("bejson-data");
if (!dataEl) return;
const bejson = JSON.parse(dataEl.textContent);
const fields = bejson.Fields;
const fi = {};
fields.forEach((f, i) => fi[f.name] = i);
const shapes = bejson.Values
.filter(r => r[fi["Record_Type_Parent"]] === "Shape")
.map(r => ({
id: r[fi["id_Shape"]] || r[fi["s_id"]],
label: r[fi["label_Shape"]] || r[fi["s_label"]],
text: r[fi["text_Shape"]] || r[fi["s_sublabel"]] || "",
x: r[fi["x_Shape"]] || r[fi["s_x"]] || 0,
y: r[fi["y_Shape"]] || r[fi["s_y"]] || 0,
w: r[fi["w_Shape"]] || 150,
h: r[fi["h_Shape"]] || 60,
color: r[fi["color_Shape"]] || r[fi["s_color"]] || THEME.accent
}));
const connectors = bejson.Values
.filter(r => r[fi["Record_Type_Parent"]] === "Connector")
.map(r => ({
from: r[fi["from_Connector"]] || r[fi["c_from"]],
to: r[fi["to_Connector"]] || r[fi["c_to"]],
label: r[fi["label_Connector"]] || r[fi["c_label"]] || ""
}));
const shapeMap = Object.fromEntries(shapes.map(s => [s.id, s]));
const connLayer = document.getElementById("connectors-layer");
const nodeLayer = document.getElementById("nodes-layer");
connectors.forEach(conn => {
const from = shapeMap[conn.from];
const to = shapeMap[conn.to];
if (!from || !to) return;
const d = `M ${from.x + from.w} ${from.y + from.h/2} C ${from.x + from.w + 50} ${from.y + from.h/2}, ${to.x - 50} ${to.y + to.h/2}, ${to.x} ${to.y + to.h/2}`;
const path = document.createElementNS("http://www.w3.org/2000/svg", "path");
path.setAttribute("d", d);
path.setAttribute("fill", "none");
path.setAttribute("stroke", from.color);
path.setAttribute("class", "conn-path");
path.setAttribute("filter", "url(#line-glow)");
connLayer.appendChild(path);
});
shapes.forEach(s => {
const g = document.createElementNS("http://www.w3.org/2000/svg", "g");
g.setAttribute("transform", `translate(${s.x},${s.y})`);
g.innerHTML = `<rect width="${s.w}" height="${s.h}" rx="8" fill="rgba(0,0,0,0.4)" stroke="${s.color}" stroke-width="2" filter="url(#glow-primary)" />
<text x="${s.w/2}" y="${s.h/2 + 5}" text-anchor="middle" fill="${s.color}" font-family="Orbitron" font-size="12">${s.label}</text>`;
nodeLayer.appendChild(g);
});
}
document.addEventListener("DOMContentLoaded", render);
</script>
</body>
</html>
"""
DEFAULT_CSS = """
*, *::before, *::after { box-sizing: border-box; margin: 0; padding: 0; }
:root { --bg: #050b17; --accent: #DE2626; --text: #e2e8f0; --muted: #64748b; }
html, body { width: 100%; height: 100%; overflow: hidden; background: var(--bg); }
.page { display: flex; flex-direction: column; height: 100vh; font-family: 'JetBrains Mono', monospace; color: var(--text); }
.title-bar { padding: 14px 28px; background: rgba(5,11,23,0.9); border-bottom: 1px solid rgba(222,38,38,0.2); backdrop-filter: blur(8px); }
h1 { font-family: 'Orbitron', sans-serif; font-size: 20px; letter-spacing: 2px; }
.diagram-wrapper { flex: 1; position: relative; overflow: hidden; }
#diagram-svg { width: 100%; height: 100%; }
.conn-path { stroke-dasharray: 5 4; animation: flow 2s linear infinite; }
@keyframes flow { from { stroke-dashoffset: 20; } to { stroke-dashoffset: 0; } }
.meta-bar { padding: 8px 28px; background: #050b17; font-size: 10px; color: var(--muted); display: flex; gap: 20px; }
"""
def export_high_fidelity_diagram(json_data, output_path, title="System Diagram", css_sheets=None):
"""
Exports a BEJSON 104db diagram as a high-fidelity HTML file.
:param css_sheets: List of paths or URLs to external CSS files.
"""
ext_css_html = ""
if css_sheets:
for sheet in css_sheets:
ext_css_html += f'<link rel="stylesheet" href="{sheet}">\\n'
timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
html = CYBERPUNK_TEMPLATE.replace("{{TITLE}}", title) \
.replace("{{SUBTITLE}}", "Relational logic map generated via BEJSON 104db") \
.replace("{{MODE}}", "HIGH-FIDELITY") \
.replace("{{ACCENT_COLOR}}", "#DE2626") \
.replace("{{BG_COLOR}}", "#050b17") \
.replace("{{INTERNAL_CSS}}", DEFAULT_CSS) \
.replace("{{EXTERNAL_CSS}}", ext_css_html) \
.replace("{{TIMESTAMP}}", timestamp) \
.replace("{{DIAGRAM_DATA}}", json.dumps(json_data, indent=2))
with open(output_path, 'w', encoding='utf-8') as f:
f.write(html)
return True