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
Files changed (1) hide show
  1. app.py +27 -19
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
- circ = 427.26
1325
- filled = circ * (clamped / 100.0)
1326
- seg = circ / 4 # ~106.8 per quarter
 
 
 
 
 
 
 
 
 
1327
  seg_colors = ["#8A4DFF", "#39C9FF", "#22B573", "#F2C14E"]
1328
- arc_elements = []
 
1329
  for idx, color in enumerate(seg_colors):
1330
- seg_start = idx * seg
1331
- if filled <= seg_start:
1332
  break
1333
- seg_filled = min(filled - seg_start, seg)
1334
- # Each arc: dasharray shows seg_filled px, hides the rest
1335
- # rotate so this segment starts at top (-90deg) + offset for prior segments
1336
- rotate_deg = -90 + (seg_start / circ) * 360
1337
- arc_elements.append(
1338
- f'<circle cx="80" cy="80" r="68" fill="none" stroke="{color}" '
1339
- f'stroke-width="7" stroke-linecap="round" '
1340
- f'stroke-dasharray="{seg_filled:.2f} {(circ - seg_filled):.2f}" '
1341
- f'stroke-dashoffset="0" '
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
- {arcs_html}
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>