15
15
16
16
from datetime import datetime
17
17
from enum import Enum
18
- from platform import node
19
18
from typing import Optional , Union , List , Dict
20
19
import re
21
20
@@ -263,7 +262,7 @@ def __init__(self, graph_styles):
263
262
self .Network ,
264
263
self .Options ,
265
264
self .IFrame ,
266
- self .BeautifulSoup
265
+ self .BeautifulSoup ,
267
266
) = self ._import_visual_modules ()
268
267
269
268
self .graph_styles = graph_styles
@@ -316,9 +315,53 @@ def _node_color(self, entity):
316
315
return self .graph_styles [entity ]["style" ]["background-color" ]
317
316
318
317
def _add_legend (self , path ):
319
- f = open (path , "r+" )
320
- soup = self .BeautifulSoup (f , 'html.parser' )
321
- print (soup .prettify ())
318
+ """Embed legend to html file generated by pyvis."""
319
+ f = open (path , "r" )
320
+ content = self .BeautifulSoup (f , "html.parser" )
321
+
322
+ legend = """
323
+ <div style="display: inline-block; font-size: 1vw; font-family: verdana;
324
+ vertical-align: top; padding: 1vw;">
325
+ <div>
326
+ <div style="background-color: rgb(246, 207, 97); width: 1.6vw; height: 1.6vw;
327
+ display: inline-block; font-size: 1.5vw; vertical-align: -0.2em;"></div>
328
+ <div style="width: 0.3vw; height: 1.5vw; display: inline-block;"></div>
329
+ <div style="display: inline-block; font-size: 1.5vw;">Trial Component</div>
330
+ </div>
331
+ <div>
332
+ <div style="background-color: rgb(255, 153, 0); width: 1.6vw; height: 1.6vw;
333
+ display: inline-block; font-size: 1.5vw; vertical-align: -0.2em;"></div>
334
+ <div style="width: 0.3vw; height: 1.5vw; display: inline-block;"></div>
335
+ <div style="display: inline-block; font-size: 1.5vw;">Context</div>
336
+ </div>
337
+ <div>
338
+ <div style="background-color: rgb(136, 195, 150); width: 1.6vw; height: 1.6vw;
339
+ display: inline-block; font-size: 1.5vw; vertical-align: -0.2em;"></div>
340
+ <div style="width: 0.3vw; height: 1.5vw; display: inline-block;"></div>
341
+ <div style="display: inline-block; font-size: 1.5vw;">Action</div>
342
+ </div>
343
+ <div>
344
+ <div style="background-color: rgb(20, 110, 180); width: 1.6vw; height: 1.6vw;
345
+ display: inline-block; font-size: 1.5vw; vertical-align: -0.2em;"></div>
346
+ <div style="width: 0.3vw; height: 1.5vw; display: inline-block;"></div>
347
+ <div style="display: inline-block; font-size: 1.5vw;">Artifact</div>
348
+ </div>
349
+ <div>
350
+ <div style="background-color: rgb(255, 255, 255); width: 1.6vw; height: 1.6vw;
351
+ display: inline-block; font-size: 0.9vw;">star</div>
352
+ <div style="width: 0.3vw; height: 1.5vw; display: inline-block;"></div>
353
+ <div style="display: inline-block; font-size: 1.5vw;">StartArn</div>
354
+ </div>
355
+ </div>
356
+ """
357
+ legend_div = self .BeautifulSoup (legend , "html.parser" )
358
+
359
+ content .div .insert_after (legend_div )
360
+
361
+ html = content .prettify ()
362
+
363
+ with open (path , "w" , encoding = "utf8" ) as file :
364
+ file .write (html )
322
365
323
366
def render (self , elements , path = "pyvisExample.html" ):
324
367
"""Render graph for lineage query result.
@@ -338,19 +381,42 @@ def render(self, elements, path="pyvisExample.html"):
338
381
display graph: The interactive visualization is presented as a static HTML file.
339
382
340
383
"""
341
- net = self .Network (height = "500px " , width = "100 %" , notebook = True , directed = True )
384
+ net = self .Network (height = "600px " , width = "82 %" , notebook = True , directed = True )
342
385
net .set_options (self ._options )
343
386
344
387
# add nodes to graph
345
388
for arn , source , entity , is_start_arn in elements ["nodes" ]:
389
+ entity_text = re .sub (r"(\w)([A-Z])" , r"\1 \2" , entity )
346
390
source = re .sub (r"(\w)([A-Z])" , r"\1 \2" , source )
347
- node_info = "Entity: " + entity + "\n " + "Type: " + source + "\n " + "Name: " + arn
391
+ account_id = re .search (r":\d{12}:" , arn )
392
+ name = re .search (r"\/.*" , arn )
393
+ node_info = (
394
+ "Entity: "
395
+ + entity_text
396
+ + "\n Type: "
397
+ + source
398
+ + "\n Account ID: "
399
+ + str (account_id .group ()[1 :- 1 ])
400
+ + "\n Name: "
401
+ + str (name .group ()[1 :])
402
+ )
348
403
if is_start_arn : # startarn
349
404
net .add_node (
350
- arn , label = source , title = node_info , color = self ._node_color (entity ), shape = "star" , borderWidth = 3
405
+ arn ,
406
+ label = source ,
407
+ title = node_info ,
408
+ color = self ._node_color (entity ),
409
+ shape = "star" ,
410
+ borderWidth = 3 ,
351
411
)
352
412
else :
353
- net .add_node (arn , label = source , title = node_info , color = self ._node_color (entity ), borderWidth = 3 )
413
+ net .add_node (
414
+ arn ,
415
+ label = source ,
416
+ title = node_info ,
417
+ color = self ._node_color (entity ),
418
+ borderWidth = 3 ,
419
+ )
354
420
355
421
# add edges to graph
356
422
for src , dest , asso_type in elements ["edges" ]:
@@ -359,7 +425,7 @@ def render(self, elements, path="pyvisExample.html"):
359
425
net .write_html (path )
360
426
self ._add_legend (path )
361
427
362
- return self .IFrame (path , width = "100%" , height = "500px " )
428
+ return self .IFrame (path , width = "100%" , height = "600px " )
363
429
364
430
365
431
class LineageQueryResult (object ):
0 commit comments