staticdash 2025.23__py3-none-any.whl → 2025.24__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- staticdash/dashboard.py +62 -55
- {staticdash-2025.23.dist-info → staticdash-2025.24.dist-info}/METADATA +1 -1
- staticdash-2025.24.dist-info/RECORD +8 -0
- staticdash-2025.23.dist-info/RECORD +0 -8
- {staticdash-2025.23.dist-info → staticdash-2025.24.dist-info}/WHEEL +0 -0
- {staticdash-2025.23.dist-info → staticdash-2025.24.dist-info}/top_level.txt +0 -0
staticdash/dashboard.py
CHANGED
|
@@ -467,33 +467,29 @@ class Dashboard:
|
|
|
467
467
|
story.append(PageBreak())
|
|
468
468
|
|
|
469
469
|
def render_page(page, level=0, sec_prefix=[]):
|
|
470
|
-
heading_style = styles
|
|
470
|
+
heading_style = styles.get(f'Heading{min(level + 1, 4)}', styles['Heading4'])
|
|
471
471
|
|
|
472
|
-
#
|
|
473
|
-
|
|
474
|
-
# story.append(Paragraph(page.title, heading_style))
|
|
475
|
-
# story.append(Spacer(1, 12))
|
|
472
|
+
# Remember where we started
|
|
473
|
+
content_start = len(story)
|
|
476
474
|
|
|
477
|
-
heading_style = styles['Heading1'] if level == 0 else styles['Heading2']
|
|
478
475
|
story.append(Paragraph(page.title, heading_style))
|
|
479
476
|
story.append(Spacer(1, 12))
|
|
480
477
|
|
|
481
|
-
|
|
482
478
|
for kind, content, _ in page.elements:
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
479
|
+
try:
|
|
480
|
+
if kind == "text":
|
|
481
|
+
story.append(Paragraph(content, normal_style))
|
|
482
|
+
story.append(Spacer(1, 8))
|
|
483
|
+
|
|
484
|
+
elif kind == "header":
|
|
485
|
+
text, lvl = content
|
|
486
|
+
safe_lvl = max(1, min(lvl + 1, 4))
|
|
487
|
+
style = styles[f'Heading{safe_lvl}']
|
|
488
|
+
story.append(Paragraph(text, style))
|
|
489
|
+
story.append(Spacer(1, 8))
|
|
490
|
+
|
|
491
|
+
elif kind == "table":
|
|
492
|
+
df = content
|
|
497
493
|
data = [df.columns.tolist()] + df.values.tolist()
|
|
498
494
|
t = Table(data, repeatRows=1)
|
|
499
495
|
t.setStyle(TableStyle([
|
|
@@ -515,48 +511,59 @@ class Dashboard:
|
|
|
515
511
|
]))
|
|
516
512
|
story.append(t)
|
|
517
513
|
story.append(Spacer(1, 12))
|
|
518
|
-
except Exception:
|
|
519
|
-
story.append(Paragraph("Table could not be rendered.", normal_style))
|
|
520
514
|
|
|
521
|
-
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
if hasattr(fig, "savefig"):
|
|
525
|
-
buf = io.BytesIO()
|
|
515
|
+
elif kind == "plot":
|
|
516
|
+
fig = content
|
|
517
|
+
buf = io.BytesIO()
|
|
518
|
+
if hasattr(fig, "savefig"):
|
|
526
519
|
fig.savefig(buf, format="png", bbox_inches="tight", dpi=300)
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
with tempfile.NamedTemporaryFile(suffix=".png", delete=False) as tmpfile:
|
|
533
|
-
fig.write_image(tmpfile.name, width=600, height=360, scale=2)
|
|
534
|
-
with open(tmpfile.name, "rb") as f:
|
|
535
|
-
story.append(Spacer(1, 8))
|
|
536
|
-
story.append(Image(io.BytesIO(f.read()), width=6*inch, height=3.6*inch))
|
|
537
|
-
story.append(Spacer(1, 12))
|
|
538
|
-
os.unlink(tmpfile.name)
|
|
539
|
-
except Exception as e:
|
|
540
|
-
story.append(Paragraph(f"Plot rendering failed: {e}", normal_style))
|
|
520
|
+
else:
|
|
521
|
+
fig.write_image(buf, format="png", width=600, height=360, scale=2)
|
|
522
|
+
buf.seek(0)
|
|
523
|
+
story.append(Image(buf, width=6 * inch, height=4.5 * inch))
|
|
524
|
+
story.append(Spacer(1, 12))
|
|
541
525
|
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
526
|
+
elif kind == "syntax":
|
|
527
|
+
code, language = content
|
|
528
|
+
from html import escape
|
|
529
|
+
story.append(Paragraph(f"<b>Code ({language}):</b>", normal_style))
|
|
530
|
+
story.append(Spacer(1, 4))
|
|
531
|
+
code_html = escape(code).replace(" ", " ").replace("\n", "<br/>")
|
|
532
|
+
story.append(Paragraph(f"<font face='Courier'>{code_html}</font>", styles['CodeBlock']))
|
|
533
|
+
story.append(Spacer(1, 12))
|
|
550
534
|
|
|
551
|
-
|
|
552
|
-
|
|
535
|
+
elif kind == "minipage":
|
|
536
|
+
render_page(content, level=level + 1, sec_prefix=sec_prefix)
|
|
553
537
|
|
|
554
|
-
|
|
538
|
+
except Exception as e:
|
|
539
|
+
story.append(Paragraph(f"Error rendering element: {e}", normal_style))
|
|
540
|
+
|
|
541
|
+
|
|
542
|
+
just_broke = False
|
|
543
|
+
|
|
544
|
+
for i, child in enumerate(page.children):
|
|
545
|
+
if i > 0 and not just_broke:
|
|
546
|
+
story.append(PageBreak())
|
|
547
|
+
|
|
548
|
+
before = len(story)
|
|
549
|
+
render_page(child, level=level + 1, sec_prefix=sec_prefix + [i + 1])
|
|
550
|
+
after = len(story)
|
|
551
|
+
|
|
552
|
+
# Determine if child added a PageBreak
|
|
553
|
+
just_broke = isinstance(story[-1], PageBreak) if after > before else False
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
# Determine if anything meaningful was added
|
|
557
|
+
def has_meaningful_content(start_idx):
|
|
558
|
+
for elem in story[start_idx:]:
|
|
559
|
+
if isinstance(elem, (Paragraph, Table, Image)):
|
|
560
|
+
return True
|
|
561
|
+
return False
|
|
562
|
+
|
|
563
|
+
if not page.children and has_meaningful_content(content_start):
|
|
555
564
|
story.append(PageBreak())
|
|
556
|
-
render_page(child, level=level + 1, sec_prefix=sec_prefix + [1])
|
|
557
565
|
|
|
558
566
|
|
|
559
|
-
story.append(PageBreak())
|
|
560
567
|
|
|
561
568
|
for page in self.pages:
|
|
562
569
|
render_page(page)
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
staticdash/__init__.py,sha256=UN_-h8wFGfTPHYjnEb7N9CsxqXo-DQVo0cmREOtvRXE,244
|
|
2
|
+
staticdash/dashboard.py,sha256=nXRAQI336HAiHaObqaA1zElnaIocQJuZUhxX_Bg8Twk,27077
|
|
3
|
+
staticdash/assets/css/style.css,sha256=RVqNdwBsaDv8izdOQjGmUZ4NROWF8uZhiq8DTNvUB1M,5962
|
|
4
|
+
staticdash/assets/js/script.js,sha256=7xBRlz_19wybbNVwAcfuKNXtDEojGB4EB0Yj4klsoTA,6998
|
|
5
|
+
staticdash-2025.24.dist-info/METADATA,sha256=ogJ8g0zXBhlVdtEMqWfSf8nS6vX5cA7dHC7IgjFEEcY,1960
|
|
6
|
+
staticdash-2025.24.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
+
staticdash-2025.24.dist-info/top_level.txt,sha256=3MzZU6SptkUkjcHV1cvPji0H4aRzPphLHnpStgGEcxM,11
|
|
8
|
+
staticdash-2025.24.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
staticdash/__init__.py,sha256=UN_-h8wFGfTPHYjnEb7N9CsxqXo-DQVo0cmREOtvRXE,244
|
|
2
|
-
staticdash/dashboard.py,sha256=pC1GI1lZ_8odSBItiZ2uJeeYKjlKLL67pNQlbMCuQNM,27296
|
|
3
|
-
staticdash/assets/css/style.css,sha256=RVqNdwBsaDv8izdOQjGmUZ4NROWF8uZhiq8DTNvUB1M,5962
|
|
4
|
-
staticdash/assets/js/script.js,sha256=7xBRlz_19wybbNVwAcfuKNXtDEojGB4EB0Yj4klsoTA,6998
|
|
5
|
-
staticdash-2025.23.dist-info/METADATA,sha256=zEz5tHigr_-tG10s_BFjPoaGvL1t8Umawj9Ajk-F3ww,1960
|
|
6
|
-
staticdash-2025.23.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
-
staticdash-2025.23.dist-info/top_level.txt,sha256=3MzZU6SptkUkjcHV1cvPji0H4aRzPphLHnpStgGEcxM,11
|
|
8
|
-
staticdash-2025.23.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|