/* =========================================================== temporal-graph-timestep.js =========================================================== */ class TemporalGraphTimestep extends HTMLElement { constructor() { super(); this._knowledge_graph = []; this._timestep = 0; this._cursorIndex = -1; } connectedCallback() { this.className = 'mermaid w-[100%] h-[100%] flex items-center justify-center'; } /** Accepts { knowledge_graph, timestep, cursorIndex } */ set data(v) { this._knowledge_graph = v.knowledge_graph; this._timestep = v.timestep; this._cursorIndex = 'cursorIndex' in v ? v.cursorIndex : -1; this.render(); } generateMermaidDiagram() { /* ---------- Mermaid init block: 36px with !important ---------- */ const initCSS = `%%{init:{ "themeCSS": ".node text{font-size:36px !important;} .edgeLabel text{font-size:36px !important;}" }}%%`; const first = this._knowledge_graph.find(r => r[3] === 0); const title = first ? first[2] : 'Temporal Graph'; /* ---------- preprocess ---------- */ const unique = []; const times = {}; const seq = {}; const firstOcc = {}; const allNodes = new Set(); this._knowledge_graph.forEach(([s,r,t,ts])=>{ const k=`${s}|${r}|${t}`; allNodes.add(s); allNodes.add(t); if(!times[k]){unique.push({s,r,t});times[k]=[];} times[k].push(ts); if(!seq[ts]) seq[ts]={cnt:1}; if(!seq[ts][k]){ seq[ts][k]=seq[ts].cnt++; if(!firstOcc[k]) firstOcc[k]={ts,seq:seq[ts][k]}; } }); const global=unique.map(o=>{ const k=`${o.s}|${o.r}|${o.t}`;return {...o,...firstOcc[k]}; }).sort((a,b)=>a.ts===b.ts? a.seq-b.seq : a.ts-b.ts); // **FIXED HERE**: The bug from before was a typo in this line. const orderIdx={}; global.forEach((o,i)=>orderIdx[`${o.s}|${o.r}|${o.t}`]=i); /* ---------- build diagram ---------- */ let code = `${initCSS} --- title: ${title} --- graph LR subgraph " " direction LR `; let linkStyle='', nodeStyle='', linkIdx=0; const activeNodes=new Set(); unique.forEach(({s,r,t})=>{ const k=`${s}|${r}|${t}`; // **RESTORED**: Using original logic for node IDs. const sId=s.replace(/\s+/g,''); const tId=t.replace(/\s+/g,''); const active=(this._timestep==='summary')||times[k].includes(this._timestep); let lb=r, sq, stp; if(active){ if(this._timestep==='summary'){sq=firstOcc[k].seq;stp=firstOcc[k].ts+1;} else{sq=seq[this._timestep][k];stp=this._timestep+1;} lb=`${stp}.${sq} ${r}`; } const highlight= active && this._cursorIndex>=0 && ( (this._timestep==='summary' && orderIdx[k]===this._cursorIndex) || (this._timestep!=='summary' && sq-1===this._cursorIndex) ); // **RESTORED**: Using original logic for creating nodes and links. if(active){ code += ` ${sId}[${s}] -->|${lb}| ${tId}[${t}]\n`; activeNodes.add(s); activeNodes.add(t); if(highlight){ linkStyle+=` linkStyle ${linkIdx} stroke:#8590F8,stroke-width:4px,color:#8590F8\n`; nodeStyle+= ` style ${sId} fill:#1A1A1A,stroke:#1A1A1A,color:#ffffff\n`+ ` style ${tId} fill:#8590F8,stroke:#8590F8,color:#ffffff\n`; } } else { code += ` ${sId}[${s}] -.-|${lb}| ${tId}[${t}]\n`; linkStyle+=` linkStyle ${linkIdx} stroke:#ffffff,stroke-width:2px,color:#ffffff\n`; } linkIdx++; }); // **RESTORED**: Using original logic for hiding inactive nodes. allNodes.forEach(n=>{ if(!activeNodes.has(n)){ nodeStyle+=` style ${n.replace(/\s+/g,'')} fill:#ffffff,stroke:#ffffff,color:#ffffff\n`; } }); return code + nodeStyle + linkStyle + 'end\n'; } // **RESTORED**: Using original, simple render method. render() { this.textContent = this.generateMermaidDiagram(); } } customElements.define('temporal-graph-timestep', TemporalGraphTimestep); /* All rights reserved Michael Anthony */