""" graph_view.py - Generiert interaktive Graph-Visualisierung (Cytoscape.js). """ import json from pathlib import Path from typing import Optional from .store import EngramStore _HTML_TEMPLATE = """ Second Brain Graph

🧠 Second Brain Graph

Knoten: Engramme (Farbe = Confidence)

Grün=hoch, Gelb=mittel, Rot=niedrig

Links: Verknüpfungen

Klicke für Details

""" def _confidence_color(conf: float) -> str: if conf >= 0.8: return "#27ae60" # Green elif conf >= 0.5: return "#f39c12" # Yellow else: return "#e74c3c" # Red def _node_size(access_count: int) -> float: return max(20, min(60, 20 + access_count * 5)) def generate_graph_html(store: EngramStore, output_path: str) -> str: """Generiert interaktive HTML-Graph-Visualisierung.""" engrams = store.get_all() nodes = [] edges = [] node_ids = set() for eg in engrams: eid = str(eg.id) conf = eg.compute_confidence() color = _confidence_color(conf) size = _node_size(eg.metadata.get("access_count", 0)) tags = ", ".join(eg.metadata.get("tags", [])) nodes.append({ "data": { "id": eid, "label": eg.content[:40] + ("..." if len(eg.content) > 40 else ""), "title": eg.content, "color": color, "size": size, "confidence": conf, "confirmed": eg.correctness.confirmed, "source": eg.metadata.get("source", "?"), "tags": tags, } }) node_ids.add(eid) for lid in eg.links: lid_s = str(lid) if lid_s in node_ids: edges.append({ "data": { "id": f"{eid}_{lid_s}", "source": eid, "target": lid_s, } }) elements = {"nodes": nodes, "edges": edges} html = _HTML_TEMPLATE.format(elements_json=json.dumps(elements, ensure_ascii=False)) out = Path(output_path) out.parent.mkdir(parents=True, exist_ok=True) with open(out, "w", encoding="utf-8") as f: f.write(html) return str(out)