1+ import { ViewColumn , window } from "vscode" ;
2+
3+ type Styles = { [ key : string ] : string } ;
4+
5+ export interface Element {
6+ data : { id : string , label : string } ,
7+ style : Styles
8+ }
9+
10+ export interface Edge {
11+ data : { id : string , source : string , target : string }
12+ }
13+
14+ interface NewNode {
15+ label : string ,
16+ styles ?: Styles ,
17+ parent ?: string ,
18+ data ?: any ;
19+ }
20+
21+ const randomId = ( ) => Math . random ( ) . toString ( 36 ) . substring ( 7 ) ;
22+
23+ export class CytoscapeGraph {
24+ private elementData = new Map < string , any > ( ) ;
25+ private elements : Element [ ] = [ ] ;
26+ private edges : Edge [ ] = [ ] ;
27+
28+ constructor ( ) { }
29+
30+ addNode ( node : NewNode ) : string {
31+ const id = randomId ( ) ; // TODO: is this unique enough?
32+
33+ if ( node . data ) {
34+ this . elementData . set ( id , node . data ) ;
35+ }
36+
37+ this . elements . push ( {
38+ data : { id, label : node . label } ,
39+ style : node . styles || { }
40+ } ) ;
41+
42+ if ( node . parent ) {
43+ this . edges . push ( {
44+ data : { id : randomId ( ) , source : node . parent , target : id }
45+ } ) ;
46+ }
47+
48+ return id ;
49+ }
50+
51+ createView ( title : string ) {
52+ const webview = window . createWebviewPanel ( `c` , title , { viewColumn : ViewColumn . One } , { enableScripts : true , retainContextWhenHidden : true } ) ;
53+ webview . webview . html = this . getHtml ( ) ;
54+
55+ return webview ;
56+ }
57+
58+ private getHtml ( ) : string {
59+ return /*html*/ `
60+ <!DOCTYPE html>
61+ <html lang="en">
62+
63+ <head>
64+ <meta charset="UTF-8">
65+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
66+ <script src="https://cdnjs.cloudflare.com/ajax/libs/cytoscape/3.23.0/cytoscape.min.js"></script>
67+ <style>
68+ /* html,
69+ body {
70+ margin: 0;
71+ padding: 0;
72+ height: 100%;
73+ width: 100%;
74+ overflow: hidden;
75+ } */
76+
77+ .diagram-container {
78+ position: absolute;
79+ top: 0;
80+ left: 0;
81+ width: 100%;
82+ height: 100%;
83+ border: none;
84+ margin: 0;
85+ }
86+ </style>
87+ </head>
88+
89+ <body>
90+ <div class="diagram-container" id="diagramContainer"></div>
91+
92+ <script>
93+ document.addEventListener("DOMContentLoaded", function () {
94+ // Initialize Cytoscape
95+ const cy = cytoscape({
96+ container: document.getElementById('diagramContainer'),
97+
98+ elements: ${ JSON . stringify ( [ ...this . elements , ...this . edges ] ) } ,
99+
100+ style: [
101+ {
102+ selector: 'node',
103+ style: {
104+ 'width': '120px',
105+ 'height': '60px',
106+ 'background-color': 'var(--vscode-list-activeSelectionBackground)',
107+ 'color': 'var(--vscode-list-activeSelectionForeground)',
108+ 'label': 'data(label)',
109+ 'text-valign': 'center',
110+ 'text-halign': 'center',
111+ 'font-size': '14px',
112+ 'text-wrap': 'wrap',
113+ 'text-max-width': '100px'
114+ }
115+ },
116+ {
117+ selector: 'edge',
118+ style: {
119+ 'width': 2,
120+ 'line-color': '#5c96bc',
121+ 'target-arrow-color': '#5c96bc',
122+ 'target-arrow-shape': 'triangle',
123+ 'curve-style': 'bezier'
124+ }
125+ }
126+ ],
127+
128+ // Layout options
129+ layout: {
130+ name: 'breadthfirst',
131+ directed: true, // Directional tree
132+ padding: 10, // Padding around the graph
133+ spacingFactor: 1.5 // Spacing between nodes
134+ }
135+ });
136+
137+ // Add click event to show alert for nodes
138+ cy.on('tap', 'node', function (evt) {
139+ const node = evt.target;
140+ console.log("You clicked: " + node.data('label'));
141+ });
142+ });
143+ </script>
144+ </body>
145+
146+ </html>
147+ ` ;
148+ }
149+ }
0 commit comments