youngtsai commited on
Commit
d24724f
·
1 Parent(s): 53fda43
Files changed (1) hide show
  1. app.py +84 -68
app.py CHANGED
@@ -1,4 +1,3 @@
1
- import networkx as nx
2
  import matplotlib.pyplot as plt
3
  import gradio as gr
4
  import io
@@ -7,10 +6,90 @@ import requests
7
  import json
8
  import os
9
 
 
 
 
10
  # Env Vars
11
  METABASE_USERNAME = os.getenv('METABASE_USERNAME')
12
  METABASE_PASSWORD = os.getenv('METABASE_PASSWORD')
13
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  def query_metabase(username, password, class_code, card_id, user_id):
15
  try:
16
  # 获取会话令牌
@@ -63,70 +142,6 @@ def query_metabase(username, password, class_code, card_id, user_id):
63
  print(f"Error: {str(e)}")
64
  return {"error": str(e)}
65
 
66
- # 创建一个DAG
67
- def create_knowledge_dag():
68
- G = nx.DiGraph()
69
-
70
- # 添加节点
71
- G.add_node("jnc-4-05-1-1", label="真分數、假分數與帶分數的命名及說、讀、聽、寫、做")
72
- G.add_node("jnc-4-05-2-1", label="假分數與帶分數的互換")
73
- G.add_node("jnc-4-05-3-1", label="同分母分數的大小比較")
74
- G.add_node("jnc-4-05-3-2", label="同分母分數的加減")
75
- G.add_node("jnc-4-05-3-3", label="分數的整數倍")
76
- G.add_node("jnc-4-06-1-1", label="認識等值分數")
77
- G.add_node("jnc-4-06-1-2", label="找出等值分數")
78
- G.add_node("jnc-4-06-2-1", label="簡單異分母分數的比較")
79
- G.add_node("jnc-4-06-2-2", label="簡單異分母分數的加減")
80
- G.add_node("jnc-4-06-3-1", label="分數與一位小數的互換")
81
- G.add_node("jnc-4-06-3-2", label="分數與二位小數的互換")
82
- G.add_node("jnc-4-08-2-1", label="認識分數數線")
83
- G.add_node("jnc-4-08-2-2", label="數線的整數、分數、小數")
84
-
85
- # 添加边
86
- G.add_edge("jnc-4-05-1-1", "jnc-4-05-2-1")
87
- G.add_edge("jnc-4-05-1-1", "jnc-4-05-3-1")
88
- G.add_edge("jnc-4-05-2-1", "jnc-4-05-3-1")
89
- G.add_edge("jnc-4-05-1-1", "jnc-4-05-3-2")
90
- G.add_edge("jnc-4-05-2-1", "jnc-4-05-3-2")
91
- G.add_edge("jnc-4-05-2-1", "jnc-4-05-3-3")
92
- G.add_edge("jnc-4-05-3-2", "jnc-4-05-3-3")
93
- G.add_edge("jnc-4-05-1-1", "jnc-4-06-1-1")
94
- G.add_edge("jnc-4-06-1-1", "jnc-4-06-1-2")
95
- G.add_edge("jnc-4-06-1-1", "jnc-4-06-2-1")
96
- G.add_edge("jnc-4-06-1-2", "jnc-4-06-2-1")
97
- G.add_edge("jnc-4-06-1-1", "jnc-4-06-2-2")
98
- G.add_edge("jnc-4-06-1-2", "jnc-4-06-2-2")
99
- G.add_edge("jnc-4-06-3-1", "jnc-4-06-3-2")
100
- G.add_edge("jnc-4-05-1-1", "jnc-4-08-2-1")
101
- G.add_edge("jnc-4-08-2-1", "jnc-4-08-2-2")
102
- G.add_edge("jnc-4-05-1-1", "jnc-4-06-3-1")
103
-
104
- return G
105
-
106
- # 绘制DAG并返回图像数据
107
- def plot_knowledge_dag():
108
- G = create_knowledge_dag()
109
-
110
- plt.figure(figsize=(10, 8))
111
- pos = nx.spring_layout(G)
112
- nx.draw(G, pos, with_labels=True, node_color='skyblue', node_size=2000, edge_color='gray', linewidths=2, font_size=10, font_weight='bold')
113
- labels = nx.get_node_attributes(G, 'label')
114
- nx.draw_networkx_labels(G, pos, labels, font_size=8, font_color='black')
115
-
116
- buf = io.BytesIO()
117
- plt.savefig(buf, format='png')
118
- buf.seek(0)
119
-
120
- return base64.b64encode(buf.read()).decode('utf-8')
121
-
122
- # 定义Gradio接口
123
- def show_knowledge_dag(result):
124
- if 'error' in result:
125
- return result['error']
126
-
127
- image_data = plot_knowledge_dag()
128
- return f'<img src="data:image/png;base64,{image_data}"/>'
129
-
130
  with gr.Blocks() as app:
131
  gr.Markdown("# Metabase Query and Visualization")
132
 
@@ -143,6 +158,7 @@ with gr.Blocks() as app:
143
  graph_html = gr.HTML()
144
 
145
  query_button = gr.Button("Fetch Data")
 
146
 
147
  query_button.click(
148
  fn=query_metabase,
@@ -150,9 +166,9 @@ with gr.Blocks() as app:
150
  outputs=result
151
  )
152
 
153
- result.change(
154
- fn=show_knowledge_dag,
155
- inputs=result,
156
  outputs=graph_html
157
  )
158
 
 
 
1
  import matplotlib.pyplot as plt
2
  import gradio as gr
3
  import io
 
6
  import json
7
  import os
8
 
9
+ from pyvis.network import Network
10
+ import networkx as nx
11
+
12
  # Env Vars
13
  METABASE_USERNAME = os.getenv('METABASE_USERNAME')
14
  METABASE_PASSWORD = os.getenv('METABASE_PASSWORD')
15
 
16
+ # Original elements
17
+ elements = [
18
+ {'data': {'id': 'jnc-4-05-1-1', 'label': '真分數、假分數與帶分數的命名及說、讀、聽、寫、做'}},
19
+ {'data': {'id': 'jnc-4-05-2-1', 'label': '假分數與帶分數的互換'}},
20
+ {'data': {'id': 'jnc-4-05-3-1', 'label': '同分母分數的大小比較'}},
21
+ {'data': {'id': 'jnc-4-05-3-2', 'label': '同分母分數的加減'}},
22
+ {'data': {'id': 'jnc-4-05-3-3', 'label': '分數的整數倍'}},
23
+ {'data': {'id': 'jnc-4-06-1-1', 'label': '認識等值分數'}},
24
+ {'data': {'id': 'jnc-4-06-1-2', 'label': '找出等值分數'}},
25
+ {'data': {'id': 'jnc-4-06-2-1', 'label': '簡單異分母分數的比較'}},
26
+ {'data': {'id': 'jnc-4-06-2-2', 'label': '簡單異分母分數的加減'}},
27
+ {'data': {'id': 'jnc-4-06-3-1', 'label': '分數與一位小數的互換'}},
28
+ {'data': {'id': 'jnc-4-06-3-2', 'label': '分數與二位小數的互換'}},
29
+ {'data': {'id': 'jnc-4-08-2-1', 'label': '認識分數數線'}},
30
+ {'data': {'id': 'jnc-4-08-2-2', 'label': '數線的整數、分數、小數'}},
31
+ {'data': {'source': 'jnc-4-05-1-1', 'target': 'jnc-4-05-2-1'}},
32
+ {'data': {'source': 'jnc-4-05-1-1', 'target': 'jnc-4-05-3-1'}},
33
+ {'data': {'source': 'jnc-4-05-2-1', 'target': 'jnc-4-05-3-1'}},
34
+ {'data': {'source': 'jnc-4-05-1-1', 'target': 'jnc-4-05-3-2'}},
35
+ {'data': {'source': 'jnc-4-05-2-1', 'target': 'jnc-4-05-3-2'}},
36
+ {'data': {'source': 'jnc-4-05-2-1', 'target': 'jnc-4-05-3-3'}},
37
+ {'data': {'source': 'jnc-4-05-3-2', 'target': 'jnc-4-05-3-3'}},
38
+ {'data': {'source': 'jnc-4-05-1-1', 'target': 'jnc-4-06-1-1'}},
39
+ {'data': {'source': 'jnc-4-06-1-1', 'target': 'jnc-4-06-1-2'}},
40
+ {'data': {'source': 'jnc-4-06-1-1', 'target': 'jnc-4-06-2-1'}},
41
+ {'data': {'source': 'jnc-4-06-1-2', 'target': 'jnc-4-06-2-1'}},
42
+ {'data': {'source': 'jnc-4-06-1-1', 'target': 'jnc-4-06-2-2'}},
43
+ {'data': {'source': 'jnc-4-06-1-2', 'target': 'jnc-4-06-2-2'}},
44
+ {'data': {'source': 'jnc-4-06-3-1', 'target': 'jnc-4-06-3-2'}},
45
+ {'data': {'source': 'jnc-4-05-1-1', 'target': 'jnc-4-08-2-1'}},
46
+ {'data': {'source': 'jnc-4-08-2-1', 'target': 'jnc-4-08-2-2'}},
47
+ {'data': {'source': 'jnc-4-05-1-1', 'target': 'jnc-4-06-3-1'}}
48
+ ]
49
+
50
+
51
+ # Create a NetworkX graph
52
+ nx_graph = nx.DiGraph()
53
+
54
+ # Add nodes and edges
55
+ for element in elements:
56
+ if 'source' not in element['data']: # It's a node
57
+ nx_graph.add_node(element['data']['id'], title=element['data']['label'])
58
+ else: # It's an edge
59
+ nx_graph.add_edge(element['data']['source'], element['data']['target'])
60
+
61
+ # Function to generate the graph in hierarchical layout
62
+ def needs_analysis():
63
+ nt = Network(directed=True)
64
+ nt.from_nx(nx_graph)
65
+ nt.repulsion(node_distance=120, central_gravity=0.0, spring_length=100, spring_strength=0.05, damping=0.09)
66
+ nt.set_options("""
67
+ {
68
+ "layout": {
69
+ "hierarchical": {
70
+ "enabled": false,
71
+ "levelSeparation": 150,
72
+ "nodeSpacing": 200,
73
+ "treeSpacing": 500,
74
+ "blockShifting": true,
75
+ "edgeMinimization": true,
76
+ "parentCentralization": true,
77
+ "direction": "UD",
78
+ "sortMethod": "directed"
79
+ }
80
+ }
81
+ }
82
+ """)
83
+ html = nt.generate_html()
84
+ # Replace single quotes with double quotes in HTML
85
+ html = html.replace("'", "\"")
86
+ return f"""<iframe style="width: 100%; height: 600px;margin:0 auto" name="result" allow="midi; geolocation; microphone; camera;
87
+ display-capture; encrypted-media;" sandbox="allow-modals allow-forms
88
+ allow-scripts allow-same-origin allow-popups
89
+ allow-top-navigation-by-user-activation allow-downloads" allowfullscreen=""
90
+ allowpaymentrequest="" frameborder="0" srcdoc='{html}'></iframe>"""
91
+
92
+
93
  def query_metabase(username, password, class_code, card_id, user_id):
94
  try:
95
  # 获取会话令牌
 
142
  print(f"Error: {str(e)}")
143
  return {"error": str(e)}
144
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
145
  with gr.Blocks() as app:
146
  gr.Markdown("# Metabase Query and Visualization")
147
 
 
158
  graph_html = gr.HTML()
159
 
160
  query_button = gr.Button("Fetch Data")
161
+ graph_btn = gr.Button("Generate Graph")
162
 
163
  query_button.click(
164
  fn=query_metabase,
 
166
  outputs=result
167
  )
168
 
169
+ graph_btn.click(
170
+ needs_analysis,
171
+ inputs=None,
172
  outputs=graph_html
173
  )
174