2020
2121# TODO: this should be a relative import of the *package*
2222import pyirk as p
23+ from pyirk .utils import render_template
2324from ipydex import IPS , activate_ips_on_exception
2425
2526__all__ = ["visualize_entity" , "visualize_all_entities" ]
@@ -437,6 +438,7 @@ def get_color_for_stm(stm: p.Statement) -> str:
437438def create_complete_graph (
438439 url_template = "" ,
439440 limit : Optional [int ] = None ,
441+ skip_auto_items : bool = False ,
440442) -> nx .DiGraph :
441443 """
442444 :param url_template: template to insert links based on uris
@@ -460,6 +462,8 @@ def create_complete_graph(
460462 continue
461463 if not isinstance (item , p .Item ) or item .short_key in ["I000" ]:
462464 continue
465+ if skip_auto_items and "Ia" in item .short_key :
466+ continue
463467 # count only items
464468 i += 1
465469 if limit and i == limit :
@@ -483,6 +487,8 @@ def create_complete_graph(
483487
484488 subj , pred , obj = stm .relation_tuple
485489 if isinstance (obj , p .Item ):
490+ if skip_auto_items and "Ia" in obj .short_key :
491+ continue
486492 if other_node := added_items_nodes .get (obj .uri ):
487493 pass
488494 else :
@@ -504,14 +510,21 @@ def create_complete_graph(
504510 return G
505511
506512
507- def render_graph_to_dot (G : nx .DiGraph ) -> str :
513+ def render_graph_to_dot (G : nx .DiGraph , center_node = None ) -> str :
508514 """
509515
510516 :param G: nx.DiGraph; the graph to render
511517 :return: dot_data
512518 """
513519
514520 ecm = build_edge_color_map (G )
521+ def get_node_color (node ):
522+ if node .short_key .startswith ("Ia" ):
523+ return "grey"
524+ elif node == center_node :
525+ return "red"
526+ else :
527+ return "black"
515528
516529 # for styling see https://nxv.readthedocs.io/en/latest/reference.html#styling
517530 style = nxv .Style (
@@ -534,7 +547,7 @@ def render_graph_to_dot(G: nx.DiGraph) -> str:
534547 "height" : 1.3 ,
535548 "shape" : d .get ("shape" , "circle" ), # see also AbstractNode.shape
536549 "style" : "filled" ,
537- "color" : "grey" if u . short_key . startswith ( "Ia" ) else "black" ,
550+ "color" : get_node_color ( u ) ,
538551 "fillcolor" : "#eeeeeedd" if "Ia" not in u .short_key else "#dddddddd" ,
539552 # Label
540553 "label" : u .get_dot_label (),
@@ -641,7 +654,7 @@ def visualize_entity(uri: str, url_template="", write_tmp_files: Union[bool, str
641654 raise p .InvalidURIError (msg )
642655
643656 small_G = nx .ego_graph (big_G , node_of_interest , radius , undirected = True ) #! perfomance of this operation sucks
644- raw_dot_data = render_graph_to_dot (small_G )
657+ raw_dot_data = render_graph_to_dot (small_G , node_of_interest )
645658
646659 dot_data0 = raw_dot_data
647660 for old , new in NEWLINE_REPLACEMENTS :
@@ -672,7 +685,7 @@ def get_label(entity):
672685 return res
673686
674687
675- def visualize_all_entities (url_template = "" , write_tmp_files : Union [bool , str ] = False ) -> str :
688+ def visualize_all_entities (url_template = "" , write_tmp_files : Union [bool , str ] = False , skip_auto_items : bool = False ) -> str :
676689 """visualize all entities loaded in datastore. output svg graph.
677690
678691 Args:
@@ -683,7 +696,7 @@ def visualize_all_entities(url_template="", write_tmp_files: Union[bool, str] =
683696 Returns:
684697 str: svg graph
685698 """
686- G = create_complete_graph (url_template )
699+ G = create_complete_graph (url_template , skip_auto_items = skip_auto_items )
687700
688701 print (f"Visualizing { len (G .nodes )} nodes and { len (G .edges )} edges." )
689702 ecm = build_edge_color_map (G )
@@ -779,13 +792,13 @@ def render_label(label: str):
779792def create_interactive_graph (url_template = "" , output_dir = "graph_site" , radius = 1 , skip_auto_items = True , skip_existing = False ):
780793 os .makedirs (output_dir , exist_ok = True )
781794
782- G = create_complete_graph (url_template )
795+ G = create_complete_graph (url_template , skip_auto_items = skip_auto_items )
783796 print (f"Visualizing { len (G .nodes )} nodes and { len (G .edges )} edges." )
784797
785798 for node in G .nodes :
786799 node_name = node .short_key
787- if skip_auto_items and "Ia" in node_name :
788- continue
800+ # if skip_auto_items and "Ia" in node_name:
801+ # continue
789802 print (node_name )
790803 dot_path = os .path .join (output_dir , f"{ node_name } .dot" )
791804 if skip_existing and os .path .isfile (dot_path ):
@@ -800,22 +813,22 @@ def create_interactive_graph(url_template="", output_dir="graph_site", radius=1,
800813 with open (cmapx_path , "r" , encoding = "utf-8" ) as f :
801814 image_map = f .read ()
802815
816+ # clean image map of replacement strings
817+ image_map = re .sub (r'(?<=href=")(.+?)(\.html".+?title=")(.+?)(?=")' , lambda mo : mo .group (1 )+ mo .group (2 )+ mo .group (1 ), image_map )
818+ desc = p .ds .items [node .uri ].R2 .value if p .ds .items [node .uri ].R2 else ""
819+ context = {
820+ "title" : node_name + " " + p .ds .items [node .uri ].R1 .value ,
821+ "img_source" : f"{ node_name } .svg" ,
822+ "map" : image_map ,
823+ "desc" : desc
824+ }
825+ res = render_template ("node_template.html" , context )
803826 with open (os .path .join (output_dir , f"{ node_name } .html" ), "w" , encoding = "utf-8" ) as f :
804- f .write (f"""<!DOCTYPE html>
805- <html>
806- <head><title>Node { node_name } </title></head>
807- <body>
808- <h1>Node { node_name } </h1>
809- <img src="{ node_name } .svg" usemap="#G" alt="Subgraph of { node_name } ">
810- { image_map }
811- <p><a href="index.html">Back to index</a></p>
812- </body>
813- </html>
814- """ )
827+ f .write (res )
815828
816829 # Index page
817830 dot_path = os .path .join (output_dir , "index.dot" )
818- visualize_all_entities (write_tmp_files = dot_path )
831+ visualize_all_entities (write_tmp_files = dot_path , skip_auto_items = skip_auto_items )
819832
820833 # create map
821834 cmapx_path = os .path .join (output_dir , f"index.map" )
@@ -825,20 +838,18 @@ def create_interactive_graph(url_template="", output_dir="graph_site", radius=1,
825838 with open (cmapx_path , "r" , encoding = "utf-8" ) as f :
826839 image_map = f .read ()
827840
841+ context = {
842+ "title" : "Overview" ,
843+ "img_source" : f"index.svg" ,
844+ "map" : image_map ,
845+ "desc" : f"Total number of Nodes: { len (G .nodes )} "
846+ }
847+ res = render_template ("node_template.html" , context )
828848 with open (os .path .join (output_dir , f"index.html" ), "w" , encoding = "utf-8" ) as f :
829- f .write (f"""<!DOCTYPE html>
830- <html>
831- <head><title>Overview</title></head>
832- <body>
833- <h1>Overview</h1>
834- <img src="index.svg" usemap="#G" alt="Overview">
835- { image_map }
836- </body>
837- </html>
838- """ )
849+ f .write (res )
839850
840851if __name__ == "__main__" :
841- # visualize_all_entities(write_tmp_files=True)
842- # create_interactive_graph()
852+ # visualize_all_entities(write_tmp_files=True, skip_auto_items=True )
853+ create_interactive_graph ()
843854 # nl = p.irkloader.load_mod_from_path("output.py", "nl", "nonlinear")
844- visualize_entity ("irk:/builtins#I31" , write_tmp_files = True , radius = 1 )
855+ # visualize_entity("irk:/builtins#I31", write_tmp_files=True, radius=1)
0 commit comments