Spaces:
Running
Running
/* =========================================================== | |
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 */ |