From 4644d33d0c23db46d706ec5667a759d6f92ebbf8 Mon Sep 17 00:00:00 2001 From: 简律纯 Date: Sat, 1 Nov 2025 19:17:41 +0800 Subject: feat: add visualization tools for character relationship graphs - Implemented ASCII visualization of relationships. - Added Graphviz support for generating PNG images of relationship graphs. - Created an interactive HTML visualization using Cytoscape.js. - Included styles and scripts for enhanced user experience in the HTML output. --- src/conventionalrp/utils/visualize_relations.py | 200 ++++++++++++++++++++++++ 1 file changed, 200 insertions(+) create mode 100644 src/conventionalrp/utils/visualize_relations.py (limited to 'src/conventionalrp/utils/visualize_relations.py') diff --git a/src/conventionalrp/utils/visualize_relations.py b/src/conventionalrp/utils/visualize_relations.py new file mode 100644 index 0000000..e5d5a9b --- /dev/null +++ b/src/conventionalrp/utils/visualize_relations.py @@ -0,0 +1,200 @@ +""" +人物关系图谱可视化工具 +""" + +import json +from typing import Dict, List + +def visualize_ascii(graph: RelationGraph): + entities = graph.get_all_entities() + + for entity in entities: + relations = graph.get_relations(entity) + if not relations: + continue + + print(f"┌─ {entity}") + for i, (rel_type, targets) in enumerate(relations.items()): + is_last = (i == len(relations) - 1) + prefix = "└─" if is_last else "├─" + + for j, target in enumerate(targets): + is_last_target = (j == len(targets) - 1) + if j == 0: + print(f"│ {prefix} [{rel_type}] → {target}") + else: + continuation = " " if is_last else "│ " + print(f"│ {continuation} └─ {target}") + print("│") + + print("=" * 60 + "\n") + +def save_graphviz(graph: RelationGraph, output_file: str = "relation_graph.png"): + """ + 使用 Graphviz 生成关系图谱图片 + """ + try: + from graphviz import Digraph + except ImportError: + print("Graphviz not installed. Install with: pip install graphviz") + return + + dot = Digraph(comment='人物关系图谱') + dot.attr(rankdir='LR') + dot.attr('node', shape='circle', style='filled', fillcolor='lightblue') + + entities = graph.get_all_entities() + for entity in entities: + dot.node(entity, entity) + + for head in graph.graph: + for relation in graph.graph[head]: + for tail in graph.graph[head][relation]: + dot.edge(head, tail, label=relation) + + dot.render(output_file.replace('.png', ''), format='png', cleanup=True) + +def generate_html_visualization(graph: RelationGraph, output_file: str = "relation_graph.html"): + """ + 生成交互式网页可视化(使用 Cytoscape.js) + """ + cytoscape_data = graph.export_cytoscape() + + html_template = """ + + + + + 人物关系图谱 + + + + +

人物关系图谱

+ +
+ + + + + """ + + with open(output_file, 'w', encoding='utf-8') as f: + f.write(html_template) \ No newline at end of file -- cgit v1.2.3-70-g09d2