1+ import React , { useEffect } from 'react' ;
2+ import * as d3 from 'd3' ; // Import D3 libraries here
3+ import ForceGraph3D from '3d-force-graph' ; // Import 3d-force-graph library here
4+ import dat from 'dat.gui' ; // Import dat.gui library here
5+ import '../stylesheets/Inspect.scss' ;
6+ import { CSS2DRenderer , CSS2DObject } from 'three/examples/jsm/renderers/CSS2DRenderer.js' ;
7+
8+
9+
10+ // currently, Insepect only works statically, but it should be possible to make it dynamic. To do so, we need to make get kubernetes resources information from the backend, and then pass it to the graph.
11+ // It will be great if future iteration group can make it dynamic.
12+
13+ const Inspect = ( ) => {
14+ useEffect ( ( ) => {
15+ // controls
16+ const controls = { 'DAG Orientation' : 'td' } ;
17+ const gui = new dat . GUI ( ) ;
18+ gui . add ( controls , 'DAG Orientation' , [ 'td' , 'bu' , 'lr' , 'rl' , 'zout' , 'zin' , 'radialout' , 'radialin' , null ] )
19+ . onChange ( orientation => graph && graph . dagMode ( orientation ) ) ;
20+
21+ // graph config
22+ const NODE_REL_SIZE = 7 ;
23+ const graph = ForceGraph3D ( {
24+ extraRenderers : [ new CSS2DRenderer ( ) ]
25+ } )
26+ . width ( 1000 )
27+ . height ( 500 )
28+ . dagMode ( 'td' )
29+ . dagLevelDistance ( 100 )
30+ . backgroundColor ( '#101020' )
31+ . linkColor ( ( ) => 'rgba(255,255,255,0.2)' )
32+ . nodeRelSize ( NODE_REL_SIZE )
33+ . nodeId ( 'path' )
34+ . nodeVal ( 'size' )
35+ . nodeLabel ( 'path' )
36+ . nodeAutoColorBy ( 'module' )
37+ . nodeOpacity ( 0.9 )
38+ . nodeLabel ( 'path' )
39+ . linkDirectionalParticles ( 2 )
40+ . linkDirectionalParticleWidth ( 1 )
41+ . linkDirectionalParticleSpeed ( 0.006 )
42+ . linkWidth ( 5 )
43+ . d3Force ( 'collision' , d3 . forceCollide ( node => Math . cbrt ( node . size ) * NODE_REL_SIZE ) )
44+ . d3VelocityDecay ( 0.3 ) ;
45+
46+ // Decrease repel intensity
47+ graph . d3Force ( 'charge' ) . strength ( - 500 ) ;
48+
49+
50+
51+ fetch ( 'http://localhost:1111/api/kuberData' )
52+ . then ( r => r . text ( ) )
53+ . then ( d3 . csvParse )
54+ . then ( data => {
55+ console . log ( data )
56+ const nodes = [ ] , links = [ ] ;
57+ data . forEach ( ( { size, path } ) => {
58+ const levels = path . split ( '/' ) ,
59+ level = levels . length - 1 ,
60+ module = level > 0 ? levels [ 1 ] : null ,
61+ leaf = levels . pop ( ) ,
62+ parent = levels . join ( '/' ) ;
63+
64+ const node = {
65+ path,
66+ leaf,
67+ module,
68+ size : + size || 20 ,
69+ level
70+ } ;
71+
72+ nodes . push ( node ) ;
73+
74+ if ( parent ) {
75+ links . push ( { source : parent , target : path , targetNode : node } ) ;
76+ }
77+ } ) ;
78+
79+
80+ graph ( document . getElementById ( 'graph' ) )
81+ . graphData ( { nodes, links } )
82+ . onNodeDragEnd ( node => {
83+ node . fx = node . x ;
84+ node . fy = node . y ;
85+ node . fz = node . z ;
86+ } )
87+ . onNodeClick ( node => {
88+ // Aim at node from outside it
89+ const distance = 40 ;
90+ const distRatio = 1 + distance / Math . hypot ( node . x , node . y , node . z ) ;
91+
92+ const newPos = node . x || node . y || node . z
93+ ? { x : node . x * distRatio , y : node . y * distRatio , z : node . z * distRatio }
94+ : { x : 0 , y : 0 , z : distance } ; // special case if node is in (0,0,0)
95+
96+ graph . cameraPosition (
97+ newPos , // new position
98+ node , // lookAt ({ x, y, z })
99+ 3000 // ms transition duration
100+ ) ;
101+
102+ // Show label
103+ const nodeEl = document . createElement ( 'div' ) ;
104+ nodeEl . innerHTML = node . path ;
105+ nodeEl . style . color = node . color ;
106+ nodeEl . className = 'node-label' ;
107+ return new CSS2DObject ( nodeEl ) ;
108+ } )
109+ . nodeThreeObject ( ( node ) => {
110+ const nodeEl = document . createElement ( 'div' ) ;
111+ nodeEl . textContent = node . path . split ( '/' ) . pop ( ) . replace ( / : .* / , '' ) ;
112+ nodeEl . style . color = node . color ;
113+ nodeEl . className = 'node-label' ;
114+ return new CSS2DObject ( nodeEl ) ;
115+ } )
116+ . nodeThreeObjectExtend ( true ) ;
117+
118+
119+ } ) ;
120+ } , [ ] ) ;
121+
122+
123+ return < div id = "Infrastructure" >
124+ < h2 > Infrastructure</ h2 >
125+ < div id = "graph" /> ;
126+ </ div >
127+ // <div id="graph" />;
128+ } ;
129+
130+ export default Inspect ;
0 commit comments