staticdash 2025.24__py3-none-any.whl → 2025.26__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 +80 -14
- {staticdash-2025.24.dist-info → staticdash-2025.26.dist-info}/METADATA +1 -1
- staticdash-2025.26.dist-info/RECORD +8 -0
- staticdash-2025.24.dist-info/RECORD +0 -8
- {staticdash-2025.24.dist-info → staticdash-2025.26.dist-info}/WHEEL +0 -0
- {staticdash-2025.24.dist-info → staticdash-2025.26.dist-info}/top_level.txt +0 -0
staticdash/dashboard.py
CHANGED
|
@@ -65,19 +65,41 @@ class Page(AbstractPage):
|
|
|
65
65
|
effective_width = self.page_width or inherited_width
|
|
66
66
|
elements = []
|
|
67
67
|
|
|
68
|
-
# Add floating header and footer for marking
|
|
68
|
+
# # Add floating header and footer for marking
|
|
69
|
+
# marking = self.marking or "Default Marking"
|
|
70
|
+
# elements.append(div(
|
|
71
|
+
# marking,
|
|
72
|
+
# cls="floating-header",
|
|
73
|
+
# style="position: fixed; top: 0; left: 50%; transform: translateX(-50%); width: auto; background-color: #f8f9fa; text-align: center; padding: 10px; z-index: 1000; font-weight: normal;"
|
|
74
|
+
# ))
|
|
75
|
+
# elements.append(div(
|
|
76
|
+
# marking,
|
|
77
|
+
# cls="floating-footer",
|
|
78
|
+
# style="position: fixed; bottom: 0; left: 50%; transform: translateX(-50%); width: auto; background-color: #f8f9fa; text-align: center; padding: 10px; z-index: 1000; font-weight: normal;"
|
|
79
|
+
# ))
|
|
80
|
+
|
|
81
|
+
# Add floating header and footer with optional distribution
|
|
69
82
|
marking = self.marking or "Default Marking"
|
|
83
|
+
distribution = getattr(self, "distribution", None)
|
|
84
|
+
|
|
70
85
|
elements.append(div(
|
|
71
86
|
marking,
|
|
72
87
|
cls="floating-header",
|
|
73
88
|
style="position: fixed; top: 0; left: 50%; transform: translateX(-50%); width: auto; background-color: #f8f9fa; text-align: center; padding: 10px; z-index: 1000; font-weight: normal;"
|
|
74
89
|
))
|
|
90
|
+
|
|
91
|
+
footer_block = []
|
|
92
|
+
if distribution:
|
|
93
|
+
footer_block.append(div(distribution, style="margin-bottom: 4px; font-size: 10pt;"))
|
|
94
|
+
footer_block.append(div(marking))
|
|
95
|
+
|
|
75
96
|
elements.append(div(
|
|
76
|
-
|
|
97
|
+
*footer_block,
|
|
77
98
|
cls="floating-footer",
|
|
78
99
|
style="position: fixed; bottom: 0; left: 50%; transform: translateX(-50%); width: auto; background-color: #f8f9fa; text-align: center; padding: 10px; z-index: 1000; font-weight: normal;"
|
|
79
100
|
))
|
|
80
101
|
|
|
102
|
+
|
|
81
103
|
for kind, content, el_width in self.elements:
|
|
82
104
|
style = ""
|
|
83
105
|
outer_style = ""
|
|
@@ -205,11 +227,12 @@ class MiniPage(AbstractPage):
|
|
|
205
227
|
return row_div
|
|
206
228
|
|
|
207
229
|
class Dashboard:
|
|
208
|
-
def __init__(self, title="Dashboard", page_width=900, marking=None):
|
|
230
|
+
def __init__(self, title="Dashboard", page_width=900, marking=None, distribution=None):
|
|
209
231
|
self.title = title
|
|
210
232
|
self.pages = []
|
|
211
233
|
self.page_width = page_width
|
|
212
234
|
self.marking = marking # Dashboard-wide marking
|
|
235
|
+
self.distribution = distribution # NEW: Distribution statement
|
|
213
236
|
|
|
214
237
|
def add_page(self, page):
|
|
215
238
|
self.pages.append(page)
|
|
@@ -431,17 +454,60 @@ class Dashboard:
|
|
|
431
454
|
self.notify('TOCEntry', (outline_level, text, self.page))
|
|
432
455
|
|
|
433
456
|
|
|
434
|
-
|
|
435
457
|
def add_marking(canvas, doc, marking):
|
|
458
|
+
from reportlab.pdfbase.pdfmetrics import stringWidth
|
|
459
|
+
|
|
460
|
+
distribution = self.distribution
|
|
461
|
+
canvas.saveState()
|
|
462
|
+
canvas.setFont("Helvetica", 10)
|
|
463
|
+
width, height = doc.pagesize
|
|
464
|
+
|
|
465
|
+
line_height = 12
|
|
466
|
+
margin_y = 36
|
|
467
|
+
|
|
468
|
+
# Top of page marking
|
|
469
|
+
if marking:
|
|
470
|
+
top_width = stringWidth(marking, "Helvetica", 10)
|
|
471
|
+
x_top = (width - top_width) / 2
|
|
472
|
+
canvas.drawString(x_top, height - margin_y, marking)
|
|
473
|
+
|
|
474
|
+
# Bottom of page — prepare to stack upward
|
|
475
|
+
y = margin_y
|
|
476
|
+
|
|
477
|
+
# First: bottom marking
|
|
436
478
|
if marking:
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
479
|
+
bot_width = stringWidth(marking, "Helvetica", 10)
|
|
480
|
+
x_bot = (width - bot_width) / 2
|
|
481
|
+
canvas.drawString(x_bot, y, marking)
|
|
482
|
+
y += line_height # make room above
|
|
483
|
+
|
|
484
|
+
# Then: bottom distribution (above marking)
|
|
485
|
+
if distribution:
|
|
486
|
+
max_width = width - 144 # ~1" margins
|
|
487
|
+
words = distribution.split()
|
|
488
|
+
lines = []
|
|
489
|
+
current_line = []
|
|
490
|
+
|
|
491
|
+
for word in words:
|
|
492
|
+
test_line = " ".join(current_line + [word])
|
|
493
|
+
if stringWidth(test_line, "Helvetica", 10) <= max_width:
|
|
494
|
+
current_line.append(word)
|
|
495
|
+
else:
|
|
496
|
+
lines.append(" ".join(current_line))
|
|
497
|
+
current_line = [word]
|
|
498
|
+
|
|
499
|
+
if current_line:
|
|
500
|
+
lines.append(" ".join(current_line))
|
|
501
|
+
|
|
502
|
+
# Draw top-down (above marking)
|
|
503
|
+
for line in reversed(lines):
|
|
504
|
+
line_width = stringWidth(line, "Helvetica", 10)
|
|
505
|
+
x = (width - line_width) / 2
|
|
506
|
+
y += line_height
|
|
507
|
+
canvas.drawString(x, y, line)
|
|
508
|
+
|
|
509
|
+
canvas.restoreState()
|
|
510
|
+
|
|
445
511
|
|
|
446
512
|
if include_title_page:
|
|
447
513
|
story.append(Spacer(1, 120))
|
|
@@ -516,9 +582,9 @@ class Dashboard:
|
|
|
516
582
|
fig = content
|
|
517
583
|
buf = io.BytesIO()
|
|
518
584
|
if hasattr(fig, "savefig"):
|
|
519
|
-
fig.savefig(buf, format="png", bbox_inches="tight", dpi=
|
|
585
|
+
fig.savefig(buf, format="png", bbox_inches="tight", dpi=600)
|
|
520
586
|
else:
|
|
521
|
-
fig.write_image(buf, format="png", width=
|
|
587
|
+
fig.write_image(buf, format="png", width=800, height=600, scale=3)
|
|
522
588
|
buf.seek(0)
|
|
523
589
|
story.append(Image(buf, width=6 * inch, height=4.5 * inch))
|
|
524
590
|
story.append(Spacer(1, 12))
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
staticdash/__init__.py,sha256=UN_-h8wFGfTPHYjnEb7N9CsxqXo-DQVo0cmREOtvRXE,244
|
|
2
|
+
staticdash/dashboard.py,sha256=7kBtiPTZ4APc7p-cnQTadeZuJ8ieWzWSfq58z7lP3tA,29660
|
|
3
|
+
staticdash/assets/css/style.css,sha256=RVqNdwBsaDv8izdOQjGmUZ4NROWF8uZhiq8DTNvUB1M,5962
|
|
4
|
+
staticdash/assets/js/script.js,sha256=7xBRlz_19wybbNVwAcfuKNXtDEojGB4EB0Yj4klsoTA,6998
|
|
5
|
+
staticdash-2025.26.dist-info/METADATA,sha256=qWw_6Tpt4UHoiJHxHuJpFkWiIdsHYqFtchk32S3l3WE,1960
|
|
6
|
+
staticdash-2025.26.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
7
|
+
staticdash-2025.26.dist-info/top_level.txt,sha256=3MzZU6SptkUkjcHV1cvPji0H4aRzPphLHnpStgGEcxM,11
|
|
8
|
+
staticdash-2025.26.dist-info/RECORD,,
|
|
@@ -1,8 +0,0 @@
|
|
|
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,,
|
|
File without changes
|
|
File without changes
|