File size: 4,657 Bytes
0cdd242
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
/* ===========================================================
   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  */