Spaces:
Sleeping
Sleeping
TOTEM Studio commited on
Commit ·
9d18faf
1
Parent(s): a59aacf
fix gauge: use SVG path arc commands instead of circle+dasharray (Gradio strips stroke attrs)
Browse files
app.py
CHANGED
|
@@ -1320,34 +1320,42 @@ def render_topbar(state: dict) -> str:
|
|
| 1320 |
|
| 1321 |
|
| 1322 |
def render_signal_gauge(value: int) -> str:
|
|
|
|
| 1323 |
clamped = max(0, min(100, int(value or 0)))
|
| 1324 |
-
|
| 1325 |
-
|
| 1326 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1327 |
seg_colors = ["#8A4DFF", "#39C9FF", "#22B573", "#F2C14E"]
|
| 1328 |
-
|
|
|
|
| 1329 |
for idx, color in enumerate(seg_colors):
|
| 1330 |
-
seg_start = idx *
|
| 1331 |
-
if
|
| 1332 |
break
|
| 1333 |
-
seg_filled = min(
|
| 1334 |
-
|
| 1335 |
-
|
| 1336 |
-
|
| 1337 |
-
|
| 1338 |
-
|
| 1339 |
-
|
| 1340 |
-
|
| 1341 |
-
|
| 1342 |
-
f'transform="rotate({rotate_deg:.1f} 80 80)" />'
|
| 1343 |
-
)
|
| 1344 |
-
arcs_html = "\n ".join(arc_elements)
|
| 1345 |
return f"""
|
| 1346 |
<div class="totem-signal-wrap">
|
| 1347 |
<svg class="totem-signal" viewBox="0 0 160 160" role="img" aria-label="TOTEM Signal {clamped} percent">
|
| 1348 |
<circle class="signal-outer-ring" cx="80" cy="80" r="76"></circle>
|
| 1349 |
<circle class="signal-track" cx="80" cy="80" r="68"></circle>
|
| 1350 |
-
{
|
| 1351 |
<circle class="signal-inner-ring" cx="80" cy="80" r="52"></circle>
|
| 1352 |
<circle class="signal-inner-ring" cx="80" cy="80" r="40"></circle>
|
| 1353 |
<path class="signal-star" d="M80 58 L84.7 73.5 L100.9 73.5 L87.8 82.9 L92.6 98.4 L80 89.1 L67.4 98.4 L72.2 82.9 L59.1 73.5 L75.3 73.5 Z"></path>
|
|
|
|
| 1320 |
|
| 1321 |
|
| 1322 |
def render_signal_gauge(value: int) -> str:
|
| 1323 |
+
import math
|
| 1324 |
clamped = max(0, min(100, int(value or 0)))
|
| 1325 |
+
total_deg = clamped * 3.6 # 0-360
|
| 1326 |
+
|
| 1327 |
+
def arc_path(cx, cy, r, start_deg, end_deg):
|
| 1328 |
+
sr = math.radians(start_deg)
|
| 1329 |
+
er = math.radians(end_deg)
|
| 1330 |
+
x1 = cx + r * math.cos(sr)
|
| 1331 |
+
y1 = cy + r * math.sin(sr)
|
| 1332 |
+
x2 = cx + r * math.cos(er)
|
| 1333 |
+
y2 = cy + r * math.sin(er)
|
| 1334 |
+
large = 1 if (end_deg - start_deg) > 180 else 0
|
| 1335 |
+
return f"M {x1:.2f} {y1:.2f} A {r} {r} 0 {large} 1 {x2:.2f} {y2:.2f}"
|
| 1336 |
+
|
| 1337 |
seg_colors = ["#8A4DFF", "#39C9FF", "#22B573", "#F2C14E"]
|
| 1338 |
+
seg_deg = 90.0
|
| 1339 |
+
paths = []
|
| 1340 |
for idx, color in enumerate(seg_colors):
|
| 1341 |
+
seg_start = idx * seg_deg
|
| 1342 |
+
if total_deg <= seg_start:
|
| 1343 |
break
|
| 1344 |
+
seg_filled = min(total_deg - seg_start, seg_deg)
|
| 1345 |
+
if seg_filled < 0.5:
|
| 1346 |
+
break
|
| 1347 |
+
svg_start = seg_start - 90 # -90 = top of circle
|
| 1348 |
+
svg_end = svg_start + seg_filled
|
| 1349 |
+
d = arc_path(80, 80, 68, svg_start, svg_end)
|
| 1350 |
+
paths.append(f'<path d="{d}" fill="none" stroke="{color}" stroke-width="7" stroke-linecap="round" />')
|
| 1351 |
+
|
| 1352 |
+
paths_html = "\n ".join(paths)
|
|
|
|
|
|
|
|
|
|
| 1353 |
return f"""
|
| 1354 |
<div class="totem-signal-wrap">
|
| 1355 |
<svg class="totem-signal" viewBox="0 0 160 160" role="img" aria-label="TOTEM Signal {clamped} percent">
|
| 1356 |
<circle class="signal-outer-ring" cx="80" cy="80" r="76"></circle>
|
| 1357 |
<circle class="signal-track" cx="80" cy="80" r="68"></circle>
|
| 1358 |
+
{paths_html}
|
| 1359 |
<circle class="signal-inner-ring" cx="80" cy="80" r="52"></circle>
|
| 1360 |
<circle class="signal-inner-ring" cx="80" cy="80" r="40"></circle>
|
| 1361 |
<path class="signal-star" d="M80 58 L84.7 73.5 L100.9 73.5 L87.8 82.9 L92.6 98.4 L80 89.1 L67.4 98.4 L72.2 82.9 L59.1 73.5 L75.3 73.5 Z"></path>
|