Spaces:
Sleeping
Sleeping
mriusero
commited on
Commit
·
1ee80e7
1
Parent(s):
3273528
feat: perf2
Browse files- src/ui/dashboard.py +39 -25
src/ui/dashboard.py
CHANGED
@@ -1,24 +1,28 @@
|
|
1 |
import gradio as gr
|
2 |
import pandas as pd
|
3 |
import asyncio
|
|
|
4 |
|
5 |
from src.production.flow import generate_data
|
6 |
from src.production.metrics.tools import tools_metrics
|
7 |
from src.production.metrics.machine import machine_metrics, fetch_issues
|
8 |
from src.ui.graphs.tools_graphs import ToolMetricsDisplay
|
9 |
|
|
|
|
|
|
|
|
|
|
|
10 |
|
11 |
async def dataflow(state):
|
12 |
"""
|
13 |
-
Main
|
|
|
14 |
"""
|
15 |
-
|
16 |
-
|
17 |
-
|
18 |
-
if 'issues' not in state['data']:
|
19 |
-
state['data']['issues'] = {}
|
20 |
|
21 |
-
if state
|
22 |
if 'gen_task' not in state or state['gen_task'] is None or state['gen_task'].done():
|
23 |
state['gen_task'] = asyncio.create_task(generate_data(state))
|
24 |
|
@@ -26,6 +30,17 @@ async def dataflow(state):
|
|
26 |
if raw_data.empty:
|
27 |
return [pd.DataFrame()] * 4
|
28 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
29 |
tools_data = await tools_metrics(raw_data)
|
30 |
tools_data = {tool: df for tool, df in tools_data.items() if not df.empty}
|
31 |
for tool, df in tools_data.items():
|
@@ -42,13 +57,11 @@ async def dataflow(state):
|
|
42 |
for i in range(1, 5)
|
43 |
]
|
44 |
|
45 |
-
|
46 |
-
def create_display_and_plots(df):
|
47 |
"""
|
48 |
-
|
49 |
"""
|
50 |
-
|
51 |
-
plots = [
|
52 |
display.normal_curve(df, cote='pos'),
|
53 |
display.gauge(df, type='cp', cote='pos'),
|
54 |
display.gauge(df, type='cpk', cote='pos'),
|
@@ -57,12 +70,10 @@ def create_display_and_plots(df):
|
|
57 |
display.gauge(df, type='cpk', cote='ori'),
|
58 |
display.control_graph(df),
|
59 |
]
|
60 |
-
return display, plots
|
61 |
-
|
62 |
|
63 |
def init_displays_and_blocks(n=4):
|
64 |
"""
|
65 |
-
|
66 |
"""
|
67 |
displays = []
|
68 |
blocks = []
|
@@ -72,24 +83,27 @@ def init_displays_and_blocks(n=4):
|
|
72 |
blocks.extend(display.tool_block(df=pd.DataFrame(), id=i))
|
73 |
return displays, blocks
|
74 |
|
75 |
-
|
76 |
-
def dashboard_ui(state):
|
77 |
"""
|
78 |
-
|
|
|
79 |
"""
|
80 |
-
|
81 |
-
|
82 |
-
async def on_tick(state):
|
83 |
dfs = await dataflow(state)
|
84 |
all_plots = []
|
85 |
-
for df in dfs:
|
86 |
-
|
87 |
all_plots.extend(plots)
|
88 |
return all_plots + [state]
|
89 |
|
90 |
-
|
|
|
|
|
|
|
|
|
|
|
91 |
timer.tick(
|
92 |
-
fn=on_tick,
|
93 |
inputs=[state],
|
94 |
outputs=initial_plots + [state]
|
95 |
)
|
|
|
1 |
import gradio as gr
|
2 |
import pandas as pd
|
3 |
import asyncio
|
4 |
+
from functools import partial
|
5 |
|
6 |
from src.production.flow import generate_data
|
7 |
from src.production.metrics.tools import tools_metrics
|
8 |
from src.production.metrics.machine import machine_metrics, fetch_issues
|
9 |
from src.ui.graphs.tools_graphs import ToolMetricsDisplay
|
10 |
|
11 |
+
MAX_ROWS = 1000
|
12 |
+
|
13 |
+
def hash_dataframe(df):
|
14 |
+
"""Computes a simple hash to detect changes in the DataFrame."""
|
15 |
+
return pd.util.hash_pandas_object(df).sum()
|
16 |
|
17 |
async def dataflow(state):
|
18 |
"""
|
19 |
+
Main function that updates data if necessary.
|
20 |
+
Avoids processing if the raw data hasn't changed.
|
21 |
"""
|
22 |
+
state.setdefault('data', {}).setdefault('tools', {})
|
23 |
+
state['data'].setdefault('issues', {})
|
|
|
|
|
|
|
24 |
|
25 |
+
if state.get('running'):
|
26 |
if 'gen_task' not in state or state['gen_task'] is None or state['gen_task'].done():
|
27 |
state['gen_task'] = asyncio.create_task(generate_data(state))
|
28 |
|
|
|
30 |
if raw_data.empty:
|
31 |
return [pd.DataFrame()] * 4
|
32 |
|
33 |
+
if len(raw_data) > MAX_ROWS:
|
34 |
+
raw_data = raw_data.tail(MAX_ROWS)
|
35 |
+
|
36 |
+
current_hash = hash_dataframe(raw_data)
|
37 |
+
if state.get('last_hash') == current_hash:
|
38 |
+
return [
|
39 |
+
pd.DataFrame(state['data']['tools'].get(f'tool_{i}', pd.DataFrame()))
|
40 |
+
for i in range(1, 5)
|
41 |
+
]
|
42 |
+
state['last_hash'] = current_hash
|
43 |
+
|
44 |
tools_data = await tools_metrics(raw_data)
|
45 |
tools_data = {tool: df for tool, df in tools_data.items() if not df.empty}
|
46 |
for tool, df in tools_data.items():
|
|
|
57 |
for i in range(1, 5)
|
58 |
]
|
59 |
|
60 |
+
def update_display_and_plots(df, display):
|
|
|
61 |
"""
|
62 |
+
Uses an existing instance of ToolMetricsDisplay to generate plots.
|
63 |
"""
|
64 |
+
return [
|
|
|
65 |
display.normal_curve(df, cote='pos'),
|
66 |
display.gauge(df, type='cp', cote='pos'),
|
67 |
display.gauge(df, type='cpk', cote='pos'),
|
|
|
70 |
display.gauge(df, type='cpk', cote='ori'),
|
71 |
display.control_graph(df),
|
72 |
]
|
|
|
|
|
73 |
|
74 |
def init_displays_and_blocks(n=4):
|
75 |
"""
|
76 |
+
Initializes the graphical objects (ToolMetricsDisplay) and their associated blocks.
|
77 |
"""
|
78 |
displays = []
|
79 |
blocks = []
|
|
|
83 |
blocks.extend(display.tool_block(df=pd.DataFrame(), id=i))
|
84 |
return displays, blocks
|
85 |
|
86 |
+
async def on_tick(state, displays):
|
|
|
87 |
"""
|
88 |
+
Tick function called periodically: updates plots only if data has changed.
|
89 |
+
Uses a lock to prevent concurrent execution.
|
90 |
"""
|
91 |
+
async with state.setdefault('lock', asyncio.Lock()):
|
|
|
|
|
92 |
dfs = await dataflow(state)
|
93 |
all_plots = []
|
94 |
+
for df, display in zip(dfs, displays):
|
95 |
+
plots = update_display_and_plots(df, display)
|
96 |
all_plots.extend(plots)
|
97 |
return all_plots + [state]
|
98 |
|
99 |
+
def dashboard_ui(state):
|
100 |
+
"""
|
101 |
+
Creates the Gradio interface and sets a refresh every second.
|
102 |
+
"""
|
103 |
+
displays, initial_plots = init_displays_and_blocks()
|
104 |
+
timer = gr.Timer(1.0)
|
105 |
timer.tick(
|
106 |
+
fn=partial(on_tick, displays=displays),
|
107 |
inputs=[state],
|
108 |
outputs=initial_plots + [state]
|
109 |
)
|