mirror of
https://github.com/OpenBB-finance/OpenBB.git
synced 2026-11-08 02:11:44 +00:00
Simplify way to generate report templates (#1788)
* simplify way to generate report templates * add documentation Co-authored-by: James Maslek <jmaslek11@gmail.com>
This commit is contained in:
194
openbb_terminal/jupyter/reports/equity.ipynb
vendored
194
openbb_terminal/jupyter/reports/equity.ipynb
vendored
@@ -434,8 +434,7 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df_sentiment_finbrain = openbb.stocks.ba.models.finbrain.get_sentiment(ticker)\n",
|
||||
"finbrain_sentiment_val = float(df_sentiment_finbrain.values[-1][0])\n",
|
||||
"finbrain_sentiment_val = 10"
|
||||
"finbrain_sentiment_val = float(df_sentiment_finbrain.values[-1][0])"
|
||||
]
|
||||
},
|
||||
{
|
||||
@@ -583,160 +582,64 @@
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"body = \"\"\n",
|
||||
"body += f'''\n",
|
||||
" <div style=\"display:flex; margin-bottom:1cm;\">\n",
|
||||
" <img src=\"data:image/png;base64,{openbb_image_encoded.decode()}\" alt=\"OpenBB\" style=\"width:144px;height:90px;\">\n",
|
||||
" <div style=\"margin-left:2em\">\n",
|
||||
" <p><b>Analyst:</b> {author}</p>\n",
|
||||
" <p><b>Date :</b> {report_date}</p>\n",
|
||||
" <p><b>Time :</b> {report_time} {report_timezone}</p>\n",
|
||||
" <br/>\n",
|
||||
" <p><b>INVESTMENT RESEARCH REPORT:</b> {ticker}</p>\n",
|
||||
" </div>\n",
|
||||
" </div>'''\n",
|
||||
"\n",
|
||||
"body += '''\n",
|
||||
" <div class=\"tab\">\n",
|
||||
" <button class=\"tablinks\" onclick=\"menu(event, 'SUMMARY')\">SUMMARY</button>\n",
|
||||
" <button class=\"tablinks\" onclick=\"menu(event, 'Overview')\">Overview</button>\n",
|
||||
" <button class=\"tablinks\" onclick=\"menu(event, 'Analysts Opinions')\">Analysts Opinions</button>\n",
|
||||
" <button class=\"tablinks\" onclick=\"menu(event, 'Fundamental Analysis')\">Fundamental Analysis</button>\n",
|
||||
" <button class=\"tablinks\" onclick=\"menu(event, 'Dark Pool and Shorts')\">Dark Pool and Shorts</button>\n",
|
||||
" <button class=\"tablinks\" onclick=\"menu(event, 'Technical Analysis')\">Technical Analysis</button>\n",
|
||||
" </br>\n",
|
||||
" <button class=\"tablinks\" onclick=\"menu(event, 'Insider Trading')\">Insider Trading</button>\n",
|
||||
" <button class=\"tablinks\" onclick=\"menu(event, 'Behavioural Analysis')\">Behavioural Analysis</button>\n",
|
||||
" <button class=\"tablinks\" onclick=\"menu(event, 'Quantitative Analysis')\">Quantitative Analysis</button>\n",
|
||||
" <button class=\"tablinks\" onclick=\"menu(event, 'Prediction Techniques')\">Prediction Techniques</button> \n",
|
||||
" </div>'''\n",
|
||||
"img = f'<img src=\"data:image/png;base64,{openbb_image_encoded.decode()}\" alt=\"OpenBB\" style=\"width:144px;\">'\n",
|
||||
"body += openbb.widgets.header(img, author, report_date, report_time, report_timezone, f'<b>INVESTMENT RESEARCH REPORT:</b> {ticker}')\n",
|
||||
"\n",
|
||||
"body += '<div id=\"SUMMARY\" class=\"tabcontent\">'\n",
|
||||
"body += '<h3>KPIs:</h3>'\n",
|
||||
"if avg_ratings_last_30_days < last_price:\n",
|
||||
" body += f'<p style=\"color:red\">❌ Last closing price ({last_price}) > Average price ratings last 30 days ({avg_ratings_last_30_days})</p>'\n",
|
||||
"else:\n",
|
||||
" body += f'<p style=\"color:green\">✅ Average price ratings last 30 days ({avg_ratings_last_30_days}) > Last closing price ({last_price})</p>'\n",
|
||||
"body += openbb.widgets.tablinks([\"SUMMARY\", \"Overview\", \"Analyst Opinions\", \"Fundamental Analysis\", \"Dark Pool and Shorts\", \"Technical Analysis\", \"Insider Trading\", \"Behavioural Analysis\", \"Quantitative Analysis\", \"Prediction Techniques\"])\n",
|
||||
"\n",
|
||||
"if regression_slope > 0:\n",
|
||||
" body += f'<p style=\"color:green\">✅ Regression on the last 30 market days ({regression_slope} dollars/market day) is positive</p>'\n",
|
||||
"else:\n",
|
||||
" body += f'<p style=\"color:red\">❌ Regression on the last 30 market days ({regression_slope} dollars/market day) is negative</p>'\n",
|
||||
" \n",
|
||||
"if rsi_value < 30:\n",
|
||||
" body += f'<p style=\"color:green\">✅ RSI level is OVERSOLD. {rsi_value} < 30</p>'\n",
|
||||
"elif rsi_value > 70:\n",
|
||||
" body += f'<p style=\"color:red\">❌ RSI level is OVERBOUGHT. {rsi_value} > 70</p>'\n",
|
||||
"else:\n",
|
||||
" body += f'<p style=\"color:orange\">🟡 RSI level is NORMAL. 30 < {rsi_value} < 70</p>'\n",
|
||||
" \n",
|
||||
"if last_10_insider_trading > 0:\n",
|
||||
" body += f'<p style=\"color:green\">✅ Last 10 insider trading. {last_10_insider_trading} M was bought in value.</p>'\n",
|
||||
"else:\n",
|
||||
" body += f'<p style=\"color:red\">❌ Last 10 insider trading. {last_10_insider_trading} M was sold in value</p>'\n",
|
||||
" \n",
|
||||
"if finbrain_sentiment_val > .1:\n",
|
||||
" body += f'<p style=\"color:green\">✅ Last FinBrain sentiment is BULLISH: {finbrain_sentiment_val} </p>'\n",
|
||||
"elif finbrain_sentiment_val < -.1:\n",
|
||||
" body += f'<p style=\"color:red\">❌ Last FinBrain sentiment is BEARISH: {finbrain_sentiment_val} </p>'\n",
|
||||
"else:\n",
|
||||
" body += f'<p style=\"color:orange\">🟡 Last FinBrain sentiment is NEUTRAL: {finbrain_sentiment_val} </p>'\n",
|
||||
" \n",
|
||||
"if (regression_val - last_price) > 0:\n",
|
||||
" body += f'<p style=\"color:green\">✅ Regression for next 20th market price ({regression_val}) > Last closing price ({last_price})</p>'\n",
|
||||
"else:\n",
|
||||
" body += f'<p style=\"color:red\">❌ Regression for next 20th market price ({regression_val}) < Last closing price ({last_price})</p>'\n",
|
||||
" \n",
|
||||
"body += '<h3>Opinion:</h3>'\n",
|
||||
"body += '</br> <p style=\"border:3px; border-style:solid; border-color:#000000; padding: 1em; width: 1050px;\" contentEditable=\"true\";></p>'\n",
|
||||
"body += '</div>'\n",
|
||||
"htmlcode = openbb.widgets.h(3, \"KPIs\")\n",
|
||||
"htmlcode += openbb.widgets.kpi([last_price], [\"Last closing price is above the average price ratings of last 30 days\", \"Average price ratings of last 30 day is above last closing price\"], avg_ratings_last_30_days)\n",
|
||||
"htmlcode += openbb.widgets.kpi([0], [\"Regression (dollars per market day) on last 30 market days is negative\", \"Regression (dollars per market day) on last 30 market days is positive\"], regression_slope)\n",
|
||||
"htmlcode += openbb.widgets.kpi([30, 70], [\"RSI level is oversold\", \"RSI level is normal\", \"RSI level is overbought\"], rsi_value) \n",
|
||||
"htmlcode += openbb.widgets.kpi([0], [\"The sum of last 10 insider trading (in millions) was negative\", \"The sum of last 10 insider trading (in millions) was positive\"], last_10_insider_trading)\n",
|
||||
"htmlcode += openbb.widgets.kpi([-.1, .1], [\"Last FinBrain sentiment is bearish\", \" Last FinBrain sentiment is neutral\", \"Last FinBrain sentiment is bullish\"], finbrain_sentiment_val) \n",
|
||||
"htmlcode += openbb.widgets.kpi([0], [\"The regression for the next 20th market price is below closing price\", \"The regression for the next 20th market price is above closing price\"], round(regression_val - last_price, 2)) \n",
|
||||
"body += openbb.widgets.add_tab(\"SUMMARY\", htmlcode)\n",
|
||||
"\n",
|
||||
"body += '<div id=\"Overview\" class=\"tabcontent\">'\n",
|
||||
"body += '</br> <p style=\"border:3px; border-style:solid; border-color:#000000; padding: 1em; width: 1050px;\" contentEditable=\"true\">No comment.</p>'\n",
|
||||
"body += openbb.widgets.row([price_chart])\n",
|
||||
"body += openbb.widgets.row([openbb.widgets.h(3, \"Description\") + openbb.widgets.p(overview)])\n",
|
||||
"body += '</div>'\n",
|
||||
"htmlcode = openbb.widgets.row([price_chart])\n",
|
||||
"htmlcode += openbb.widgets.row([openbb.widgets.h(3, \"Description\") + openbb.widgets.p(overview)])\n",
|
||||
"body += openbb.widgets.add_tab(\"Overview\", htmlcode)\n",
|
||||
"\n",
|
||||
"body += '<div id=\"Analysts Opinions\" class=\"tabcontent\">'\n",
|
||||
"body += '</br> <p style=\"border:3px; border-style:solid; border-color:#000000; padding: 1em; width: 1050px;\" contentEditable=\"true\">No comment.</p>'\n",
|
||||
"body += openbb.widgets.row([price_target_chart])\n",
|
||||
"body += openbb.widgets.row([ratings_over_time_chart])\n",
|
||||
"body += openbb.widgets.row([df_analyst.to_html()])\n",
|
||||
"body += '</div>'\n",
|
||||
"htmlcode = openbb.widgets.row([price_target_chart])\n",
|
||||
"htmlcode += openbb.widgets.row([ratings_over_time_chart])\n",
|
||||
"htmlcode += openbb.widgets.row([df_analyst.to_html()])\n",
|
||||
"body += openbb.widgets.add_tab(\"Analyst Opinions\", htmlcode)\n",
|
||||
"\n",
|
||||
"body += '<div id=\"Fundamental Analysis\" class=\"tabcontent\">'\n",
|
||||
"body += '</br> <p style=\"border:3px; border-style:solid; border-color:#000000; padding: 1em; width: 1050px;\" contentEditable=\"true\">No comment.</p>'\n",
|
||||
"body += openbb.widgets.row([openbb.widgets.h(3, \"Estimates\") + df_year_estimates.head().to_html()])\n",
|
||||
"body += openbb.widgets.row([openbb.widgets.h(3, \"Earnings\") + df_quarter_earnings.head().to_html()])\n",
|
||||
"body += openbb.widgets.row([openbb.widgets.h(3, \"Revenues\") + df_quarter_revenues.head().to_html()])\n",
|
||||
"body += openbb.widgets.row([openbb.widgets.h(3, \"SEC filings\") + df_sec_filings.head().to_html()])\n",
|
||||
"body += '</div>'\n",
|
||||
"htmlcode = openbb.widgets.row([openbb.widgets.h(3, \"Estimates\") + df_year_estimates.head().to_html()])\n",
|
||||
"htmlcode += openbb.widgets.row([openbb.widgets.h(3, \"Earnings\") + df_quarter_earnings.head().to_html()])\n",
|
||||
"htmlcode += openbb.widgets.row([openbb.widgets.h(3, \"Revenues\") + df_quarter_revenues.head().to_html()])\n",
|
||||
"htmlcode += openbb.widgets.row([openbb.widgets.h(3, \"SEC filings\") + df_sec_filings.head().to_html()])\n",
|
||||
"body += openbb.widgets.add_tab(\"Fundamental Analysis\", htmlcode)\n",
|
||||
" \n",
|
||||
"htmlcode = openbb.widgets.row([net_short_position])\n",
|
||||
"htmlcode += openbb.widgets.row([price_vs_short_interest])\n",
|
||||
"htmlcode += openbb.widgets.row([dark_pools])\n",
|
||||
"htmlcode += openbb.widgets.row([volexch])\n",
|
||||
"body += openbb.widgets.add_tab(\"Dark Pool and Shorts\", htmlcode)\n",
|
||||
"\n",
|
||||
"body += '<div id=\"Dark Pool and Shorts\" class=\"tabcontent\">'\n",
|
||||
"body += '</br> <p style=\"border:3px; border-style:solid; border-color:#000000; padding: 1em; width: 1050px;\" contentEditable=\"true\">No comment.</p>'\n",
|
||||
"body += openbb.widgets.row([net_short_position])\n",
|
||||
"body += openbb.widgets.row([price_vs_short_interest])\n",
|
||||
"body += openbb.widgets.row([dark_pools])\n",
|
||||
"body += openbb.widgets.row([volexch])\n",
|
||||
"body += '</div>'\n",
|
||||
"body += openbb.widgets.add_tab(\"Technical Analysis\", openbb.widgets.row([ta_rsi]))\n",
|
||||
"\n",
|
||||
"body += '<div id=\"Technical Analysis\" class=\"tabcontent\">'\n",
|
||||
"body += '</br> <p style=\"border:3px; border-style:solid; border-color:#000000; padding: 1em; width: 1050px;\" contentEditable=\"true\">No comment.</p>'\n",
|
||||
"body += openbb.widgets.row([ta_rsi])\n",
|
||||
"body += '</div>'\n",
|
||||
"htmlcode = openbb.widgets.row([openbb.widgets.h(3, \"Last Activity\") + df_insider.head(10).to_html(col_space='75px')])\n",
|
||||
"body += openbb.widgets.add_tab(\"Insider Trading\", htmlcode)\n",
|
||||
"\n",
|
||||
"body += '<div id=\"Insider Trading\" class=\"tabcontent\">'\n",
|
||||
"body += '</br> <p style=\"border:3px; border-style:solid; border-color:#000000; padding: 1em; width: 1050px;\" contentEditable=\"true\">No comment.</p>'\n",
|
||||
"body += openbb.widgets.row([openbb.widgets.h(3, \"Last Activity\") + df_insider.head(10).to_html(col_space='75px')])\n",
|
||||
"body += '</div>'\n",
|
||||
"htmlcode = openbb.widgets.row([finbrain_sentiment])\n",
|
||||
"htmlcode += openbb.widgets.row([snews])\n",
|
||||
"htmlcode += openbb.widgets.row([openbb.widgets.h(3, \"Stocktwits\") + stocktwits_sentiment])\n",
|
||||
"body += openbb.widgets.add_tab(\"Behavioural Analysis\", htmlcode)\n",
|
||||
"\n",
|
||||
"htmlcode = openbb.widgets.row([bw_month])\n",
|
||||
"htmlcode += openbb.widgets.row([bw_year])\n",
|
||||
"body += openbb.widgets.add_tab(\"Quantitative Analysis\", htmlcode)\n",
|
||||
"\n",
|
||||
"body += '<div id=\"Behavioural Analysis\" class=\"tabcontent\">'\n",
|
||||
"body += '</br> <p style=\"border:3px; border-style:solid; border-color:#000000; padding: 1em; width: 1050px;\" contentEditable=\"true\">No comment.</p>'\n",
|
||||
"body += openbb.widgets.row([finbrain_sentiment])\n",
|
||||
"body += openbb.widgets.row([snews])\n",
|
||||
"body += openbb.widgets.row([openbb.widgets.h(3, \"Stocktwits\") + stocktwits_sentiment])\n",
|
||||
"body += '</div>'\n",
|
||||
"htmlcode = openbb.widgets.row([regression])\n",
|
||||
"htmlcode += openbb.widgets.row([mc])\n",
|
||||
"body += openbb.widgets.add_tab(\"Prediction Techniques\", htmlcode)\n",
|
||||
"\n",
|
||||
"body += '<div id=\"Quantitative Analysis\" class=\"tabcontent\">'\n",
|
||||
"body += '</br> <p style=\"border:3px; border-style:solid; border-color:#000000; padding: 1em; width: 1050px;\" contentEditable=\"true\">No comment.</p>'\n",
|
||||
"body += openbb.widgets.row([bw_month])\n",
|
||||
"body += openbb.widgets.row([bw_year])\n",
|
||||
"body += '</div>'\n",
|
||||
"\n",
|
||||
"body += '<div id=\"Prediction Techniques\" class=\"tabcontent\">'\n",
|
||||
"body += '</br> <p style=\"border:3px; border-style:solid; border-color:#000000; padding: 1em; width: 1050px;\" contentEditable=\"true\">No comment.</p>'\n",
|
||||
"body += openbb.widgets.row([regression])\n",
|
||||
"body += openbb.widgets.row([mc])\n",
|
||||
"body += '</div>'\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"body += '''\n",
|
||||
" <script>\n",
|
||||
" function menu(evt, menu_name) {\n",
|
||||
" var i, tabcontent, tablinks;\n",
|
||||
" tabcontent = document.getElementsByClassName(\"tabcontent\");\n",
|
||||
" for (i = 0; i < tabcontent.length; i++) {\n",
|
||||
" tabcontent[i].style.display = \"none\";\n",
|
||||
" }\n",
|
||||
" tablinks = document.getElementsByClassName(\"tablinks\");\n",
|
||||
" for (i = 0; i < tablinks.length; i++) {\n",
|
||||
" tablinks[i].className = tablinks[i].className.replace(\" active\", \"\");\n",
|
||||
" tablinks[i].style.backgroundColor = \"white\";\n",
|
||||
" tablinks[i].style.color = \"black\";\n",
|
||||
" }\n",
|
||||
" document.getElementById(menu_name).style.display = \"block\";\n",
|
||||
" \n",
|
||||
" evt.currentTarget.className += \" active\";\n",
|
||||
" evt.currentTarget.style.backgroundColor = \"black\";\n",
|
||||
" evt.currentTarget.style.color = \"white\";\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" window.onload=function(){\n",
|
||||
" menu(event, 'SUMMARY');\n",
|
||||
" };\n",
|
||||
" </script>'''\n",
|
||||
"body += openbb.widgets.tab_clickable_evt()\n",
|
||||
"\n",
|
||||
"report = openbb.widgets.html_report(title=report_name, stylesheet=stylesheet, body=body)\n",
|
||||
"\n",
|
||||
"# to save the results\n",
|
||||
"with open(report_name + \".html\", \"w\") as fh:\n",
|
||||
" fh.write(report)"
|
||||
@@ -745,7 +648,7 @@
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "c692b8cf-8b9f-420f-bc01-c7b9cc7e7dd4",
|
||||
"id": "e15cef06-0d10-4153-b6d3-9762be0ed1dd",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
@@ -757,7 +660,8 @@
|
||||
"hash": "aa1c4d436101635411b2afa2ce061827695b6e3d0efa7f05338cbf11ad26165e"
|
||||
},
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3.8.12 64-bit ('gst': conda)",
|
||||
"display_name": "Python 3 (ipykernel)",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
@@ -770,7 +674,7 @@
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.12"
|
||||
"version": "3.8.6"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
|
||||
@@ -75,23 +75,205 @@ def html_report(title: str = "", stylesheet: str = "", body: str = "") -> str:
|
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), "widgets", "report.j2")
|
||||
) as f:
|
||||
template = Template(f.read())
|
||||
card = template.render(title=title, stylesheet=stylesheet, body=body)
|
||||
return card
|
||||
return template.render(title=title, stylesheet=stylesheet, body=body)
|
||||
|
||||
|
||||
def h(level: int, text: str) -> str:
|
||||
"""Wrap text into an HTML `h` tag."""
|
||||
"""Wrap text into an HTML `h` tag.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
level : int
|
||||
HTML `h` level tag
|
||||
text : str
|
||||
Contents for `h` level tag
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
HTML code as string
|
||||
"""
|
||||
return f"<h{str(level)}>{text}</h{level}>"
|
||||
|
||||
|
||||
def p(text: str) -> str:
|
||||
"""Wrap text into an HTML `p` tag."""
|
||||
"""Wrap text into an HTML `p` tag.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
text : str
|
||||
Contents for HTML `p` tag
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
HTML code as string
|
||||
"""
|
||||
return f"<p>{text}</p>"
|
||||
|
||||
|
||||
def row(elements: List) -> str:
|
||||
"""HTML code elements to add in a single row
|
||||
|
||||
Parameters
|
||||
----------
|
||||
elements : List
|
||||
List of HTML code elements to add in a row
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
HTML code as string
|
||||
"""
|
||||
with open(
|
||||
os.path.join(os.path.dirname(os.path.abspath(__file__)), "widgets", "row.j2")
|
||||
) as f:
|
||||
template = Template(f.read())
|
||||
return template.render(elements=elements)
|
||||
|
||||
|
||||
def kpi(thresholds: List[float], sentences: List[str], value: float) -> str:
|
||||
"""Add new key performance indicator to main page of report
|
||||
|
||||
Parameters
|
||||
----------
|
||||
thresholds : List[float]
|
||||
List of thresholds to take into account
|
||||
sentences : List[str]
|
||||
List of sentences to take into account. len(sentences) = len(thresholds)+1
|
||||
value : float
|
||||
Current value for the KPI in question
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
HTML code as string
|
||||
"""
|
||||
if len(thresholds) == 1 and len(sentences) == 2:
|
||||
if value < thresholds[0]:
|
||||
return f'<p style="color:red">❌ {sentences[0]}. {value} < {thresholds[0]} </p>'
|
||||
return f'<p style="color:green">✅ {sentences[1]}. {value} > {thresholds[0]} </p>'
|
||||
if len(thresholds) == 2 and len(sentences) == 3:
|
||||
if value < thresholds[0]:
|
||||
return f'<p style="color:red">❌ {sentences[0]}. {value} < {thresholds[0]} </p>'
|
||||
if value > thresholds[1]:
|
||||
return f'<p style="color:green">✅ {sentences[2]}. {value} > {thresholds[1]} </p>'
|
||||
return f'<p style="color:orange">🟡 {sentences[1]}. {thresholds[0]} < {value} < {thresholds[1]} </p>'
|
||||
print("Error. KPI condition is not correctly set")
|
||||
return ""
|
||||
|
||||
|
||||
def add_tab(title: str, htmlcode: str) -> str:
|
||||
"""Add new tab section for the report. By default adds an opinion editable box at the start.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
title : str
|
||||
Title associated with this tab / section
|
||||
htmlcode : str
|
||||
All HTML code contain within this section
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
HTML code as string
|
||||
"""
|
||||
return f"""<div id="{title}" class="tabcontent"></br>
|
||||
<p style="border:3px; border-style:solid;
|
||||
border-color:#000000; padding: 1em; width: 1050px;" contentEditable="true">
|
||||
No comment.
|
||||
</p>{htmlcode}
|
||||
</div>"""
|
||||
|
||||
|
||||
def tab_clickable_evt() -> str:
|
||||
"""Adds javascript code within HTML at the bottom that allows the interactivity with tabs.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
javascript code in HTML to process interactive tabs
|
||||
"""
|
||||
return """
|
||||
<script>
|
||||
function menu(evt, menu_name) {
|
||||
var i, tabcontent, tablinks;
|
||||
tabcontent = document.getElementsByClassName("tabcontent");
|
||||
for (i = 0; i < tabcontent.length; i++) {
|
||||
tabcontent[i].style.display = "none";
|
||||
}
|
||||
tablinks = document.getElementsByClassName("tablinks");
|
||||
for (i = 0; i < tablinks.length; i++) {
|
||||
tablinks[i].className = tablinks[i].className.replace(" active", "");
|
||||
tablinks[i].style.backgroundColor = "white";
|
||||
tablinks[i].style.color = "black";
|
||||
}
|
||||
document.getElementById(menu_name).style.display = "block";
|
||||
|
||||
evt.currentTarget.className += " active";
|
||||
evt.currentTarget.style.backgroundColor = "black";
|
||||
evt.currentTarget.style.color = "white";
|
||||
}
|
||||
|
||||
window.onload=function(){
|
||||
menu(event, 'SUMMARY');
|
||||
};
|
||||
</script>"""
|
||||
|
||||
|
||||
def tablinks(tabs: List[str]) -> str:
|
||||
"""Adds list of tabs/sections for the reports that are able to be clicked. For every 6 tabs we push them onto a new line.
|
||||
|
||||
Parameters
|
||||
----------
|
||||
tabs : List[str]
|
||||
List of tabs/sections for the reports.
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
HTML code for interactive tabs
|
||||
"""
|
||||
htmlcode = '<div class="tab">'
|
||||
for idx, tab in enumerate(tabs):
|
||||
htmlcode += f"""<button class="tablinks" onclick="menu(event, '{tab}')">{tab}</button>"""
|
||||
if ((idx + 1) % 5) == 0:
|
||||
htmlcode += "</br>"
|
||||
htmlcode += "</div>"
|
||||
return htmlcode
|
||||
|
||||
|
||||
def header(img, author, report_date, report_time, report_tz, title) -> str:
|
||||
"""Creates reports header
|
||||
|
||||
Parameters
|
||||
----------
|
||||
img : str
|
||||
Image for customizable report
|
||||
author : str
|
||||
Name of author responsible by report
|
||||
report_date : str
|
||||
Date when report is run
|
||||
report_time : str
|
||||
Time when report is run
|
||||
report_tz : str
|
||||
Timezone associated with datetime of report being run
|
||||
title : str
|
||||
Title of the report
|
||||
|
||||
Returns
|
||||
-------
|
||||
str
|
||||
HTML code for interactive tabs
|
||||
"""
|
||||
return f"""
|
||||
<div style="display:flex; margin-bottom:1cm;">
|
||||
{img}
|
||||
<div style="margin-left:2em">
|
||||
<p><b>Analyst:</b> {author}</p>
|
||||
<p><b>Date :</b> {report_date}</p>
|
||||
<p><b>Time :</b> {report_time} {report_tz}</p>
|
||||
<br/>
|
||||
<p>{title}</p>
|
||||
</div>
|
||||
</div>"""
|
||||
|
||||
Reference in New Issue
Block a user