@@ -429,107 +429,151 @@ def execute_operation(self, operation):
429429 elif operation == "Draw Graph" :
430430 try :
431431 graph = GraphRepresentation .build_graph (self .parent .file_path )
432- G = nx . DiGraph ( )
432+ network_analysis = NetworkAnalysis ( graph )
433433
434- # Add edges from graph representation
435- for edge in graph . edges :
436- G . add_edge ( edge [ 0 ], edge [ 1 ] )
434+ # Get most active and influential users for highlighting
435+ most_active = network_analysis . get_most_active_user ()
436+ most_influential = network_analysis . get_most_influencer_user ( )
437437
438- visualizer = GraphVisualizer (G )
438+ visualizer = GraphVisualizer (graph )
439439
440+ # Clear the output frame's text
440441 output_frame = self .parent .frames ['OutputFrame' ]
441442 output_frame .output_text .delete ('1.0' , ctk .END )
442443
443- # Save visualization to a temp file first
444+ # Save visualization to a temp file
444445 temp_dir = os .path .dirname (self .parent .file_path )
445446 temp_graph_path = os .path .join (temp_dir , "temp_graph.png" )
446- visualizer .visualize (save_path = temp_graph_path )
447447
448- # Show the path in output frame
449- output_frame .output_text .insert (ctk .END , f"Graph visualization saved as: { temp_graph_path } " )
448+ visualizer .visualize (
449+ save_path = temp_graph_path ,
450+ most_active_users = most_active if isinstance (most_active , list ) else [
451+ most_active ] if most_active else None ,
452+ most_influential_users = most_influential if isinstance (most_influential , list ) else [
453+ most_influential ] if most_influential else None
454+ )
455+
456+ # Create informative text output
457+ output_content = """Graph Analysis Summary:
458+ Network Visualization has been generated with the following details:
459+
460+ 1. Node Information:
461+ - All users are represented as nodes
462+ - Node colors indicate user types:
463+
464+ * Light Blue: Regular users
465+ * Red: Most active users
466+ * Green: Most influential users
467+ * Purple: Users who are both active and influential
468+
469+ 2. Edge Information:
470+ - Arrows show follower relationships
471+ - Arrow direction: From user -> to follower
472+
473+ 3. Layout:
474+ - Spring layout is used for node positioning
475+ - Nodes are spaced for optimal visibility
476+ - Labels show user names and IDs
477+
478+ You can find the complete visualization at:
479+ {}
480+ Note: The graph has been saved as a PNG file which you can open with any image viewer for a detailed examination.""" .format (
481+ temp_graph_path )
450482
483+ # Insert the formatted text
484+ output_frame .output_text .insert ('1.0' , output_content )
451485 output_frame .status_label .configure (
452486 text = "Graph Generated Successfully" ,
453487 text_color = "#10b981"
454488 )
455489
456- self .parent .show_frame ("OutputFrame" )
490+ # Show success message
491+ messagebox .showinfo ("Success" ,
492+ "Graph has been generated and saved successfully.\n You can find it at: " + temp_graph_path )
457493
494+ self .parent .show_frame ("OutputFrame" )
458495 except Exception as e :
459496 messagebox .showerror ("Error" , f"Failed to generate graph: { str (e )} " )
460497
461- elif operation == "Most Active User" : # can't be tested yet
498+ elif operation == "Most Active User" :
462499 graph = GraphRepresentation .build_graph (self .parent .file_path )
463500 analyzer = NetworkAnalysis (graph )
464-
465- most_active_id = analyzer .get_most_active_user ()
466- most_active_user = graph .get_user (most_active_id )
467-
468- output_content = f"""Most Active User Analysis:
469-
470- User ID: { most_active_user .id }
471- Name: { most_active_user .name }
472- Number of Followers: { len (most_active_user .followers )}
473- Number of Posts: { len (most_active_user .posts )}
474-
475- Posts:
476- """
477-
478- for post in most_active_user .posts :
479- output_content += f"\n Post Body: { post .body } \n Topics: { ', ' .join (post .topics )} \n "
501+ most_active_ids = analyzer .get_most_active_user ()
502+
503+ if not most_active_ids :
504+ messagebox .showinfo ("No Results" , "No active users found in the network." )
505+ return
506+
507+ # Convert to list if single ID returned
508+ if not isinstance (most_active_ids , list ):
509+ most_active_ids = [most_active_ids ]
510+
511+ output_content = "Most Active User Analysis:\n \n "
512+ for most_active_id in most_active_ids :
513+ most_active_user = graph .get_user (most_active_id )
514+ if most_active_user :
515+ output_content += f"User ID: { most_active_user .id } \n "
516+ output_content += f"Name: { most_active_user .name } \n "
517+ output_content += f"Number of Followers: { len (most_active_user .followers )} \n "
518+ output_content += f"Number of Posts: { len (most_active_user .posts )} \n \n "
519+ output_content += "Posts:\n "
520+ for post in most_active_user .posts :
521+ output_content += f"\n Post Body: { post .body } \n Topics: { ', ' .join (post .topics )} \n "
522+ output_content += "\n -------------------\n \n "
480523
481524 # Update OutputFrame
482525 output_frame = self .parent .frames ['OutputFrame' ]
483526 output_frame .output_text .delete ('1.0' , ctk .END )
484527 output_frame .output_text .insert (ctk .END , output_content )
485528
486529 output_frame .status_label .configure (
487- text = "Most Active User Found Successfully" ,
530+ text = "Most Active User(s) Found Successfully" ,
488531 text_color = "#10b981"
489532 )
490-
491- # Navigate to OutputFrame
492533 self .parent .show_frame ("OutputFrame" )
493534
494- elif operation == "Top Influencer" : # can't be tested yet
495- # Create graph and analysis objects
535+ elif operation == "Top Influencer" :
496536 graph = GraphRepresentation .build_graph (self .parent .file_path )
497537 analyzer = NetworkAnalysis (graph )
498-
499- # Get top influencer
500- influencer_id = analyzer .get_most_influencer_user ()
501- influencer = graph .get_user (influencer_id )
502-
503- # Prepare output content
504- output_content = f"""Top Influencer Analysis:
505-
506- User ID: { influencer .id }
507- Name: { influencer .name }
508- Number of Followers: { len (influencer .followers )}
509- Number of Posts: { len (influencer .posts )}
510-
511- Influence Metrics:
512- - Direct Followers: { len (influencer .followers )}
513- - Total Posts: { len (influencer .posts )}
514- - Average Topics per Post: { sum (len (post .topics ) for post in influencer .posts ) / len (influencer .posts ) if influencer .posts else 0 :.2f}
515-
516- Recent Posts:
517- """
518-
519- for post in influencer .posts [- 5 :]: # Show last 5 posts
520- output_content += f"\n Post Body: { post .body } \n Topics: { ', ' .join (post .topics )} \n "
538+ influencer_ids = analyzer .get_most_influencer_user ()
539+
540+ if not influencer_ids :
541+ messagebox .showinfo ("No Results" , "No influential users found in the network." )
542+ return
543+
544+ # Convert to list if single ID returned
545+ if not isinstance (influencer_ids , list ):
546+ influencer_ids = [influencer_ids ]
547+
548+ output_content = "Top Influencer Analysis:\n \n "
549+ for influencer_id in influencer_ids :
550+ influencer = graph .get_user (influencer_id )
551+ if influencer :
552+ output_content += f"User ID: { influencer .id } \n "
553+ output_content += f"Name: { influencer .name } \n "
554+ output_content += f"Number of Followers: { len (influencer .followers )} \n "
555+ output_content += f"Number of Posts: { len (influencer .posts )} \n \n "
556+ output_content += "Influence Metrics:\n "
557+ output_content += f"- Direct Followers: { len (influencer .followers )} \n "
558+ output_content += f"- Total Posts: { len (influencer .posts )} \n "
559+ avg_topics = sum (len (post .topics ) for post in influencer .posts ) / len (
560+ influencer .posts ) if influencer .posts else 0
561+ output_content += f"- Average Topics per Post: { avg_topics :.2f} \n \n "
562+ output_content += "Recent Posts:\n "
563+ for post in influencer .posts [- 5 :]:
564+ output_content += f"\n Post Body: { post .body } \n Topics: { ', ' .join (post .topics )} \n "
565+
566+ output_content += "\n -------------------\n \n "
521567
522568 # Update OutputFrame
523569 output_frame = self .parent .frames ['OutputFrame' ]
524570 output_frame .output_text .delete ('1.0' , ctk .END )
525571 output_frame .output_text .insert (ctk .END , output_content )
526572
527573 output_frame .status_label .configure (
528- text = "Top Influencer Found Successfully" ,
574+ text = "Top Influencer(s) Found Successfully" ,
529575 text_color = "#10b981"
530576 )
531-
532- # Navigate to OutputFrame
533577 self .parent .show_frame ("OutputFrame" )
534578
535579 elif operation == "Mutual Users" :
0 commit comments