openseries 2.1.2__tar.gz → 2.1.3__tar.gz
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.
- {openseries-2.1.2 → openseries-2.1.3}/PKG-INFO +1 -1
- {openseries-2.1.2 → openseries-2.1.3}/openseries/report.py +76 -21
- {openseries-2.1.2 → openseries-2.1.3}/pyproject.toml +1 -1
- {openseries-2.1.2 → openseries-2.1.3}/LICENSE.md +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/README.md +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/__init__.py +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/_common_model.py +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/_risk.py +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/datefixer.py +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/frame.py +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/load_plotly.py +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/owntypes.py +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/plotly_captor_logo.json +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/plotly_layouts.json +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/portfoliotools.py +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/py.typed +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/series.py +0 -0
- {openseries-2.1.2 → openseries-2.1.3}/openseries/simulation.py +0 -0
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
from __future__ import annotations
|
|
4
4
|
|
|
5
|
+
import re
|
|
5
6
|
import webbrowser
|
|
6
7
|
from inspect import stack
|
|
7
8
|
from logging import getLogger
|
|
@@ -16,7 +17,7 @@ if TYPE_CHECKING: # pragma: no cover
|
|
|
16
17
|
from plotly.graph_objs import Figure # type: ignore[import-untyped]
|
|
17
18
|
|
|
18
19
|
from .frame import OpenFrame
|
|
19
|
-
from .owntypes import
|
|
20
|
+
from .owntypes import LiteralPlotlyOutput
|
|
20
21
|
|
|
21
22
|
|
|
22
23
|
from pandas import DataFrame, Index, Series, Timestamp, concat
|
|
@@ -857,7 +858,9 @@ def _generate_responsive_html_string(
|
|
|
857
858
|
f"{mobile_content}\n"
|
|
858
859
|
f"</div>\n"
|
|
859
860
|
"<style>\n"
|
|
861
|
+
"html, body { height: 100%; margin: 0; padding: 0; }\n"
|
|
860
862
|
"body { overflow-y: auto; }\n"
|
|
863
|
+
".plotly-desktop { min-height: 100vh; }\n"
|
|
861
864
|
"@media (max-width: 960px), (pointer: coarse), (hover: none) {\n"
|
|
862
865
|
" .plotly-desktop { display: none !important; }\n"
|
|
863
866
|
" .plotly-mobile { display: block !important; "
|
|
@@ -890,16 +893,7 @@ def _generate_responsive_html_string(
|
|
|
890
893
|
"overflow-x: hidden !important; }\n"
|
|
891
894
|
" .plotly-desktop .js-plotly-plot > div { "
|
|
892
895
|
"overflow: hidden !important; overflow-y: hidden !important; "
|
|
893
|
-
"overflow-x: hidden !important;
|
|
894
|
-
" .plotly-desktop .js-plotly-plot svg { "
|
|
895
|
-
"overflow: hidden !important; }\n"
|
|
896
|
-
" .plotly-desktop * { "
|
|
897
|
-
"overflow-y: hidden !important; }\n"
|
|
898
|
-
' .plotly-desktop [style*="overflow"] { '
|
|
899
|
-
"overflow: hidden !important; overflow-y: hidden !important; }\n"
|
|
900
|
-
" .plotly-desktop .scrollbar-kit { "
|
|
901
|
-
"display: none !important; visibility: hidden !important; "
|
|
902
|
-
"opacity: 0 !important; }\n"
|
|
896
|
+
"overflow-x: hidden !important; }\n"
|
|
903
897
|
" .plotly-desktop .scrollbar-slider { "
|
|
904
898
|
"display: none !important; visibility: hidden !important; "
|
|
905
899
|
"opacity: 0 !important; }\n"
|
|
@@ -1236,10 +1230,27 @@ def _generate_responsive_html_string(
|
|
|
1236
1230
|
'desktopContainer.style.display !== "none") {\n'
|
|
1237
1231
|
" adjustTableSize(desktopContainer);\n"
|
|
1238
1232
|
" adjustLogoPosition(desktopContainer);\n"
|
|
1233
|
+
" var plotDiv = desktopContainer.querySelector("
|
|
1234
|
+
"'.js-plotly-plot');\n"
|
|
1235
|
+
" if (plotDiv && typeof Plotly !== 'undefined') {\n"
|
|
1236
|
+
" Plotly.Plots.resize(plotDiv);\n"
|
|
1237
|
+
" }\n"
|
|
1239
1238
|
" }\n"
|
|
1240
1239
|
" }, 100);\n"
|
|
1241
1240
|
" });\n"
|
|
1242
1241
|
" updateLayout();\n"
|
|
1242
|
+
" // Set desktop plot container to full viewport height on load\n"
|
|
1243
|
+
" setTimeout(function() {\n"
|
|
1244
|
+
f" var desktopContainer = {desktop_get};\n"
|
|
1245
|
+
" if (desktopContainer && typeof Plotly !== 'undefined') {\n"
|
|
1246
|
+
" var plotDiv = desktopContainer.querySelector("
|
|
1247
|
+
"'.js-plotly-plot');\n"
|
|
1248
|
+
" if (plotDiv) {\n"
|
|
1249
|
+
" plotDiv.style.height = window.innerHeight + 'px';\n"
|
|
1250
|
+
" Plotly.Plots.resize(plotDiv);\n"
|
|
1251
|
+
" }\n"
|
|
1252
|
+
" }\n"
|
|
1253
|
+
" }, 100);\n"
|
|
1243
1254
|
" var checkInterval = setInterval(function() {\n"
|
|
1244
1255
|
f" var mobileContainer = {mobile_get};\n"
|
|
1245
1256
|
f" var desktopContainer = {desktop_get};\n"
|
|
@@ -1267,6 +1278,36 @@ def _generate_responsive_html_string(
|
|
|
1267
1278
|
)
|
|
1268
1279
|
|
|
1269
1280
|
|
|
1281
|
+
def _wrap_in_full_html(
|
|
1282
|
+
responsive_content: str,
|
|
1283
|
+
) -> str:
|
|
1284
|
+
"""Wrap responsive HTML content in a full HTML document.
|
|
1285
|
+
|
|
1286
|
+
Args:
|
|
1287
|
+
responsive_content: The responsive HTML content (divs, CSS, JS).
|
|
1288
|
+
|
|
1289
|
+
Returns:
|
|
1290
|
+
Full HTML document string.
|
|
1291
|
+
"""
|
|
1292
|
+
plotly_js_script = (
|
|
1293
|
+
'<script src="https://cdn.plot.ly/plotly-latest.min.js"></script>'
|
|
1294
|
+
)
|
|
1295
|
+
|
|
1296
|
+
return (
|
|
1297
|
+
"<!DOCTYPE html>\n"
|
|
1298
|
+
'<html lang="en">\n'
|
|
1299
|
+
"<head>\n"
|
|
1300
|
+
' <meta charset="utf-8" />\n'
|
|
1301
|
+
" <title>Plotly Report</title>\n"
|
|
1302
|
+
f" {plotly_js_script}\n"
|
|
1303
|
+
"</head>\n"
|
|
1304
|
+
"<body>\n"
|
|
1305
|
+
f"{responsive_content}\n"
|
|
1306
|
+
"</body>\n"
|
|
1307
|
+
"</html>"
|
|
1308
|
+
)
|
|
1309
|
+
|
|
1310
|
+
|
|
1270
1311
|
def report_html(
|
|
1271
1312
|
data: OpenFrame,
|
|
1272
1313
|
bar_freq: LiteralBizDayFreq = "BYE",
|
|
@@ -1274,7 +1315,6 @@ def report_html(
|
|
|
1274
1315
|
title: str | None = None,
|
|
1275
1316
|
directory: Path | None = None,
|
|
1276
1317
|
output_type: LiteralPlotlyOutput = "file",
|
|
1277
|
-
include_plotlyjs: LiteralPlotlyJSlib = "cdn",
|
|
1278
1318
|
*,
|
|
1279
1319
|
auto_open: bool = False,
|
|
1280
1320
|
add_logo: bool = True,
|
|
@@ -1289,9 +1329,6 @@ def report_html(
|
|
|
1289
1329
|
title: The report page title.
|
|
1290
1330
|
directory: Directory where Plotly HTML file is saved.
|
|
1291
1331
|
output_type: Determines output type. Defaults to "file".
|
|
1292
|
-
include_plotlyjs: Determines how the plotly.js library is included in
|
|
1293
|
-
the output.
|
|
1294
|
-
Defaults to "cdn".
|
|
1295
1332
|
auto_open: Determines whether to open a browser window with the plot.
|
|
1296
1333
|
Defaults to False.
|
|
1297
1334
|
add_logo: If True a Captor logo is added to the plot. Defaults to True.
|
|
@@ -1299,7 +1336,13 @@ def report_html(
|
|
|
1299
1336
|
labels. Defaults to False.
|
|
1300
1337
|
|
|
1301
1338
|
Returns:
|
|
1302
|
-
|
|
1339
|
+
A tuple containing:
|
|
1340
|
+
- Plotly Figure object (the desktop version of the figure)
|
|
1341
|
+
- When ``output_type="file"``: A string containing the file path to the
|
|
1342
|
+
saved HTML file
|
|
1343
|
+
- When ``output_type="div"``: A string containing the responsive HTML div
|
|
1344
|
+
section (includes both desktop and mobile layouts with CSS and
|
|
1345
|
+
JavaScript)
|
|
1303
1346
|
|
|
1304
1347
|
"""
|
|
1305
1348
|
copied = data.from_deepcopy()
|
|
@@ -1389,12 +1432,14 @@ def report_html(
|
|
|
1389
1432
|
div_id_desktop = filename.split(sep=".")[0] + "_desktop"
|
|
1390
1433
|
div_id_mobile = filename.split(sep=".")[0] + "_mobile"
|
|
1391
1434
|
|
|
1392
|
-
|
|
1435
|
+
figure.update_layout(height=None)
|
|
1436
|
+
|
|
1437
|
+
html_desktop_raw = to_html(
|
|
1393
1438
|
fig=figure,
|
|
1394
1439
|
div_id=div_id_desktop,
|
|
1395
1440
|
auto_play=False,
|
|
1396
1441
|
full_html=False,
|
|
1397
|
-
include_plotlyjs=
|
|
1442
|
+
include_plotlyjs="cdn",
|
|
1398
1443
|
config=fig["config"],
|
|
1399
1444
|
)
|
|
1400
1445
|
|
|
@@ -1407,16 +1452,23 @@ def report_html(
|
|
|
1407
1452
|
config=fig["config"],
|
|
1408
1453
|
)
|
|
1409
1454
|
|
|
1455
|
+
script_pattern = r'<script src="https://cdn\.plot\.ly/plotly[^"]*"></script>'
|
|
1456
|
+
html_desktop_content = re.sub(script_pattern, "", html_desktop_raw)
|
|
1457
|
+
|
|
1410
1458
|
responsive_html = _generate_responsive_html_string(
|
|
1411
|
-
html_desktop=
|
|
1459
|
+
html_desktop=html_desktop_content,
|
|
1412
1460
|
html_mobile=html_mobile,
|
|
1413
1461
|
div_id_desktop=div_id_desktop,
|
|
1414
1462
|
div_id_mobile=div_id_mobile,
|
|
1415
1463
|
table_html=table_html,
|
|
1416
1464
|
)
|
|
1417
1465
|
|
|
1466
|
+
full_html = _wrap_in_full_html(
|
|
1467
|
+
responsive_content=responsive_html,
|
|
1468
|
+
)
|
|
1469
|
+
|
|
1418
1470
|
with plotfile.open(mode="w", encoding="utf-8") as f:
|
|
1419
|
-
f.write(
|
|
1471
|
+
f.write(full_html)
|
|
1420
1472
|
|
|
1421
1473
|
if auto_open:
|
|
1422
1474
|
webbrowser.open(f"file://{plotfile.resolve()}")
|
|
@@ -1425,12 +1477,15 @@ def report_html(
|
|
|
1425
1477
|
else:
|
|
1426
1478
|
div_id = filename.split(sep=".")[0]
|
|
1427
1479
|
div_id_mobile = div_id + "_mobile"
|
|
1480
|
+
|
|
1481
|
+
figure.update_layout(height=None)
|
|
1482
|
+
|
|
1428
1483
|
html_desktop = to_html(
|
|
1429
1484
|
fig=figure,
|
|
1430
1485
|
div_id=div_id,
|
|
1431
1486
|
auto_play=False,
|
|
1432
1487
|
full_html=False,
|
|
1433
|
-
include_plotlyjs=
|
|
1488
|
+
include_plotlyjs="cdn",
|
|
1434
1489
|
config=fig["config"],
|
|
1435
1490
|
)
|
|
1436
1491
|
html_mobile = to_html(
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|