mirror of
https://github.com/MaaAssistantArknights/MaaAssistantArknights.git
synced 2026-07-15 17:30:27 +08:00
chore: remove TaskTransitionVisualizer
This commit is contained in:
3
tools/TasksTransitionVisualizer/.gitignore
vendored
3
tools/TasksTransitionVisualizer/.gitignore
vendored
@@ -1,3 +0,0 @@
|
||||
|
||||
*.pdf
|
||||
testenv/
|
||||
@@ -1,15 +0,0 @@
|
||||
# 说明
|
||||
|
||||
一个简单脚本,读取tasks.json, 根据指定的前缀词筛选task,将获得的task按照next关系绘制成有向图。
|
||||
|
||||
Generate a transition graph for nodes whose name begin with a specific keyword
|
||||
|
||||
```
|
||||
optional arguments:
|
||||
-h, --help show this help message and exit
|
||||
--keyword KEYWORD the keyword to generate the graph for, case sensitive
|
||||
--nodesize [400-800] the size of nodes in the graph
|
||||
--arrowsize [20-50] the size of arrows in the graph
|
||||
--fontsize [5-10] the size of font in the graph
|
||||
--list if list all the names of nodes matched
|
||||
```
|
||||
@@ -1,37 +0,0 @@
|
||||
backcall==0.2.0
|
||||
colorama==0.4.4
|
||||
contourpy==1.0.7
|
||||
cycler==0.11.0
|
||||
decorator==5.0.9
|
||||
ffmpeg==1.4
|
||||
fonttools==4.38.0
|
||||
importlib-resources==5.12.0
|
||||
ipykernel==5.5.5
|
||||
ipython==7.24.1
|
||||
ipython-genutils==0.2.0
|
||||
jedi==0.18.0
|
||||
jupyter-client==6.1.12
|
||||
jupyter-core==4.7.1
|
||||
kiwisolver==1.4.4
|
||||
matplotlib==3.7.1
|
||||
matplotlib-inline==0.1.2
|
||||
networkx==3.0
|
||||
numpy==1.24.2
|
||||
packaging==23.0
|
||||
parso==0.8.2
|
||||
pickleshare==0.7.5
|
||||
Pillow==9.4.0
|
||||
prompt-toolkit==3.0.18
|
||||
pydot==1.4.2
|
||||
Pygments==2.9.0
|
||||
pyparsing==3.0.9
|
||||
python-dateutil==2.8.1
|
||||
pywin32==301
|
||||
pyzmq==22.1.0
|
||||
six==1.16.0
|
||||
tornado==6.1
|
||||
traitlets==5.0.5
|
||||
urllib3==1.25.11
|
||||
wcwidth==0.2.5
|
||||
you-get==0.4.1536
|
||||
zipp==3.15.0
|
||||
@@ -1,122 +0,0 @@
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import logging
|
||||
import warnings
|
||||
import argparse
|
||||
import matplotlib.pyplot as plt
|
||||
import networkx as nx
|
||||
import webbrowser
|
||||
|
||||
# nx.nx_pydot.graphviz_layout reports DeprecationWarning
|
||||
warnings.filterwarnings('ignore', category=DeprecationWarning)
|
||||
|
||||
logging.basicConfig(format='%(message)s', level=logging.INFO)
|
||||
|
||||
parser = argparse.ArgumentParser(
|
||||
description='Generate a transition graph for nodes whose name begin with a specific keyword')
|
||||
parser.add_argument('--keyword', type=str, default='Mizuki@Roguelike',
|
||||
help='the keyword to generate the graph for, case sensitive')
|
||||
parser.add_argument('--nodesize', type=int, default=500, choices=range(400, 801), metavar='[400-800]',
|
||||
help='the size of nodes in the graph')
|
||||
parser.add_argument('--arrowsize', type=int, default=30, choices=range(20, 51), metavar='[20-50]',
|
||||
help='the size of arrows in the graph')
|
||||
parser.add_argument('--fontsize', type=int, default=8, choices=range(5, 11), metavar='[5-10]',
|
||||
help='the size of font in the graph')
|
||||
parser.add_argument('--list', action='store_true',
|
||||
help='if list all the names of nodes matched')
|
||||
args = parser.parse_args()
|
||||
|
||||
project_root_path = os.path.normpath(os.path.join(os.path.dirname(os.path.abspath(__file__)),
|
||||
os.pardir, os.pardir))
|
||||
task_json_path = os.path.join(project_root_path, 'resource', 'tasks.json')
|
||||
try:
|
||||
with open(task_json_path, 'r', encoding='utf-8') as f:
|
||||
json_dict = json.load(f)
|
||||
except Exception as e:
|
||||
logging.error(
|
||||
"Failed to read task json at {}: {}".format(task_json_path), e)
|
||||
exit(-1)
|
||||
|
||||
keyword = args.keyword
|
||||
if keyword == "Mizuki@Roguelike":
|
||||
logging.info("Default to generate graph for {}".format(keyword))
|
||||
else:
|
||||
logging.info("Generating graph for %s", keyword)
|
||||
|
||||
|
||||
def simplify_node(node_name):
|
||||
# shorten node name for display in the graph
|
||||
return node_name.replace(keyword+'@', '')
|
||||
|
||||
|
||||
def recover_node(node_name):
|
||||
# recover the node names, used when build graph
|
||||
return keyword+'@'+node_name
|
||||
|
||||
# recursively find the nodes
|
||||
def search_node(node, s, visited, nodes):
|
||||
# nodes without next field are not considered
|
||||
if not (node in json_dict.keys() and 'next' in json_dict[node]):
|
||||
return
|
||||
if node in visited:
|
||||
return
|
||||
visited.add(node)
|
||||
if node.startswith(s):
|
||||
nodes.append(simplify_node(node))
|
||||
else:
|
||||
return
|
||||
for next_node in json_dict[node]['next']:
|
||||
search_node(next_node, s, visited, nodes)
|
||||
|
||||
|
||||
visited = set()
|
||||
nodes = []
|
||||
for node in json_dict:
|
||||
search_node(node, keyword, visited, nodes)
|
||||
|
||||
if len(nodes) == 0:
|
||||
logging.warning("Found 0 tasks starting with {}".format(keyword))
|
||||
exit(0)
|
||||
else:
|
||||
logging.info('Found {} tasks starting with {}'.format(len(nodes), keyword))
|
||||
if args.list:
|
||||
logging.info('\n'.join(nodes))
|
||||
nodes.sort()
|
||||
|
||||
# generate networkx.MultiDiGraph
|
||||
G = {}
|
||||
for node in nodes:
|
||||
G[node] = json_dict[recover_node(node)]['next']
|
||||
for i in range(len(G[node])):
|
||||
G[node][i] = simplify_node(G[node][i])
|
||||
G = nx.MultiDiGraph(G)
|
||||
logging.info("Built graph model completed.")
|
||||
|
||||
# export pdf
|
||||
plt.figure(figsize=(60, 60))
|
||||
pos = nx.nx_pydot.graphviz_layout(G, prog='dot')
|
||||
nx.draw_networkx_nodes(G, pos, node_size=args.nodesize,
|
||||
alpha=0.8, node_color='lightblue')
|
||||
nx.draw_networkx_edges(G, pos, alpha=1, arrows=True, arrowsize=args.arrowsize)
|
||||
nx.draw_networkx_labels(G, pos, font_size=args.fontsize,
|
||||
font_family='sans-serif')
|
||||
plt.axis('off')
|
||||
fig = plt.gcf()
|
||||
relative_path = os.path.join(
|
||||
"tools", "TasksTransitionVisualizer", "graph_{}.pdf".format(keyword))
|
||||
file_path = os.path.join(project_root_path, relative_path)
|
||||
|
||||
try:
|
||||
fig.savefig(file_path)
|
||||
logging.info("Transition graph file for keyword {} saved to {}".format(
|
||||
keyword, relative_path))
|
||||
except PermissionError:
|
||||
logging.error(
|
||||
"File {} is in use. Close and re-run the task.".format(file_path))
|
||||
except Exception as e:
|
||||
logging.error(
|
||||
"Cannot save graph file at {}. Error: {}".format(relative_path, e))
|
||||
|
||||
|
||||
webbrowser.open(file_path, new=2)
|
||||
Reference in New Issue
Block a user