diff --git a/cara/apps/calculator/__init__.py b/cara/apps/calculator/__init__.py index 15572267..dbfa15ef 100644 --- a/cara/apps/calculator/__init__.py +++ b/cara/apps/calculator/__init__.py @@ -33,7 +33,7 @@ from .user import AuthenticatedUser, AnonymousUser # calculator version. If the calculator needs to make breaking changes (e.g. change # form attributes) then it can also increase its MAJOR version without needing to # increase the overall CARA version (found at ``cara.__version__``). -__version__ = "2.0.0" +__version__ = "2.1.0" class BaseRequestHandler(RequestHandler): diff --git a/cara/apps/calculator/report_generator.py b/cara/apps/calculator/report_generator.py index 261dd8d8..d1bff9dc 100644 --- a/cara/apps/calculator/report_generator.py +++ b/cara/apps/calculator/report_generator.py @@ -165,7 +165,7 @@ def _img2bytes(figure): def _figure2bytes(figure): # Draw the image img_data = io.BytesIO() - figure.savefig(img_data, format='png', bbox_inches="tight") + figure.savefig(img_data, format='png', bbox_inches="tight", transparent=True) return img_data @@ -388,7 +388,7 @@ class ReportGenerator: context['qr_code'] = generate_qr_code(base_url, self.calculator_prefix, form) context['calculator_prefix'] = self.calculator_prefix context['scale_warning'] = { - 'level': 'Yellow - 2', + 'level': 'yellow-2', 'incidence_rate': 'lower than 25 new cases per 100 000 inhabitants', 'onsite_access': 'of about 8000', 'threshold': '' diff --git a/cara/apps/calculator/static/css/report.css b/cara/apps/calculator/static/css/report.css index f6efde67..0e0a7cf7 100644 --- a/cara/apps/calculator/static/css/report.css +++ b/cara/apps/calculator/static/css/report.css @@ -1,87 +1,250 @@ #body { - top: 10px; - left: 20px; - bottom: 20px; - right: 20px; - padding: 20px; + top: 10px; + left: 20px; + bottom: 20px; + right: 20px; + padding: 20px; } h1 { - text-align: center; + text-align: center; } .subtitle { - text-align: center; - font-size: 13pt; - padding-bottom: 15pt; + text-align: center; + font-size: 17px; + padding-bottom: 20px; } p.data_italic { - font-style: italic; + font-style: italic; } p.data_title { - font-weight: bold; + font-weight: bold; } p.data_text { - padding-left: 30px; + padding-left: 30px; } p.data_subtext { - padding-left: 60px; - margin-left: -3em; + padding-left: 60px; + margin-left: -3em; } p.result_title { - font-weight: bold; - font-size: 15pt; + font-weight: bold; + font-size: 20px; } p.image { - text-align: center; - font-size: 13pt; + text-align: center; + font-size: 17px; } p.disclaimer { - font-size: 12pt; + font-size: 16px; } p.notes { - font-size: 10pt; + font-size: 13px; +} + +#cara_logo { + height: 150px; + margin: 1% +} + +#pdf-qr-code { + margin-right: 1%; + width: 100pt; } .red_bkg { - color: #000000; - background-color: #CD5C5C; - text-decoration: none; + color: #000000; + background-color: #CD5C5C; + text-decoration: none; } .yellow_bkg { - color: #000000; - background-color: #FFFF00; - text-decoration: none; + color: #000000; + background-color: #FFFF00; + text-decoration: none; } .green_bkg { - color: #000000; - background-color: #90EE90; - text-decoration: none; + color: #000000; + background-color: #90EE90; + text-decoration: none; } -.warning_image_png { - margin-bottom: 1rem; - padding-left: 30px; - border-radius: .25rem +.icon_button { + border: none; + background: none; } -.warning_text { - height:fit-content; - align-self: center; - margin-left: 5% +.icon_button:focus { + outline: 0 !important; } -/* Flexbox layouts */ -.flex { - display: flex; +.nav-tabs .nav-item .nav-link.active { + font-weight: bold; +} + +.nav-tabs .nav-item .nav-link { + color: black; +} + +.tabs-div { + margin: 1%; + border: #DFDFDF 1px solid; + border-radius: 5px; +} + +.print-button { + margin-left: auto; + margin-right: 1%; +} + +/* @media (width: 1200px) { */ +@media print { + /* #body { + min-width: 1200px; + } */ + #results, + #rules, + #data { + display: contents!important; + } + #link_reproduce_results { + display: none!important; + } + #pdf-qr-code { + visibility: inherit!important; + } + .collapse { + display: block!important; + } + .tab-content { + border-top: none!important; + } + .nav-tabs { + display: none!important; + } + .tabs-div { + border: none!important; + } + .icon_button { + display: none!important; + } + .print-button { + display: none!important; + } + .card { + page-break-inside: avoid; + } + /* CSS styling to avoid page breaks. */ + .break-after { + page-break-after: always; + } + .break-avoid { + page-break-inside: avoid; + } +} + + +/* CSS for the animation */ + +.intro-banner-vdo-play-btn { + height: 60px; + width: 60px; + position: relative; + text-align: center; + border-radius: 100px; + z-index: 1 +} + +.intro-banner-vdo-play-btn i { + line-height: 56px; + font-size: 30px +} + +.intro-banner-vdo-play-btn .ripple { + position: absolute; + width: 160px; + height: 160px; + z-index: -1; + left: 50%; + top: 50%; + opacity: 0; + margin: -80px 0 0 -80px; + border-radius: 100px; + -webkit-animation: ripple 1.8s infinite; + animation: ripple 1.8s infinite +} + +@-webkit-keyframes ripple { + 0% { + opacity: 1; + -webkit-transform: scale(0); + transform: scale(0) + } + 100% { + opacity: 0; + -webkit-transform: scale(1); + transform: scale(1) + } +} + +@keyframes ripple { + 0% { + opacity: 1; + -webkit-transform: scale(0); + transform: scale(0) + } + 100% { + opacity: 0; + -webkit-transform: scale(1); + transform: scale(1) + } +} + +.intro-banner-vdo-play-btn .ripple:nth-child(2) { + animation-delay: .3s; + -webkit-animation-delay: .3s +} + +.intro-banner-vdo-play-btn .ripple:nth-child(3) { + animation-delay: .6s; + -webkit-animation-delay: .6s +} + +.split { + /* flex: 1; */ + clear: both; + display: inline-flex; + flex-direction: column; + width: 100%; +} + +@media screen and (min-width: 40em) { + .split { + flex-direction: row; + } + .split>* { + flex-basis: 100%; + } + .header-text { + text-align: left; + } + .split>*+* { + margin-left: 2em; + } + .bigButton { + width: 25%; + } + .logo { + float: left; + } } \ No newline at end of file diff --git a/cara/apps/calculator/static/images/warning_scale/Level1.png b/cara/apps/calculator/static/images/warning_scale/green-1.png similarity index 100% rename from cara/apps/calculator/static/images/warning_scale/Level1.png rename to cara/apps/calculator/static/images/warning_scale/green-1.png diff --git a/cara/apps/calculator/static/images/warning_scale/Level3.png b/cara/apps/calculator/static/images/warning_scale/orange-3.png similarity index 100% rename from cara/apps/calculator/static/images/warning_scale/Level3.png rename to cara/apps/calculator/static/images/warning_scale/orange-3.png diff --git a/cara/apps/calculator/static/images/warning_scale/Level4.png b/cara/apps/calculator/static/images/warning_scale/red-4.png similarity index 100% rename from cara/apps/calculator/static/images/warning_scale/Level4.png rename to cara/apps/calculator/static/images/warning_scale/red-4.png diff --git a/cara/apps/calculator/static/images/warning_scale/Level2.png b/cara/apps/calculator/static/images/warning_scale/yellow-2.png similarity index 100% rename from cara/apps/calculator/static/images/warning_scale/Level2.png rename to cara/apps/calculator/static/images/warning_scale/yellow-2.png diff --git a/cara/apps/calculator/static/js/pdf.js b/cara/apps/calculator/static/js/pdf.js new file mode 100644 index 00000000..6afb4fea --- /dev/null +++ b/cara/apps/calculator/static/js/pdf.js @@ -0,0 +1,29 @@ +function generate_pdf_version(qr_link) { + const pdf_version = this.document.getElementById("body"); + + // PDF styling + var opt = { + filename: 'myfile.pdf', + image: { type: 'jpeg', quality: 0.98 }, + html2canvas: { scale: 2, width: 1200, windowWidth: 1200 }, + enableLinks: false, + jsPDF: { + unit: 'pt', + format: 'letter', + orientation: 'portrait', + }, + pagebreak: { mode: '', avoid: '.break-avoid' }, + }; + html2pdf().set(opt).from(pdf_version).toPdf().get('pdf').then(function(pdf) { + var totalPages = pdf.internal.getNumberOfPages(); + pdf.setPage(1); + pdf.link(530, 25, 60, 60, { url: qr_link }); //Hyperlink to reproduce results + + for (i = 1; i <= totalPages; i++) { + pdf.setPage(i); + pdf.setFontSize(10); + pdf.setTextColor(150); + pdf.text('Page ' + i + ' of ' + totalPages, (pdf.internal.pageSize.getWidth() / 2.25), (pdf.internal.pageSize.getHeight() - 10)); + } + }).save(); +}; \ No newline at end of file diff --git a/cara/apps/calculator/static/js/report.js b/cara/apps/calculator/static/js/report.js index d1f0d92f..d1105bec 100644 --- a/cara/apps/calculator/static/js/report.js +++ b/cara/apps/calculator/static/js/report.js @@ -26,11 +26,11 @@ function draw_concentration_plot(svg_id, times, concentrations, exposed_presence // Plot tittle. vis.append('svg:foreignObject') + .attr("background-color", "transparent") .attr('width', width) .attr('height', margins.top) - .append('xhtml:body') .style('text-align', 'center') - .html('Mean concentration of virions'); + .html('Mean concentration of virions'); // Line representing the mean concentration. var lineFunc = d3.line() @@ -181,4 +181,4 @@ function draw_concentration_plot(svg_id, times, concentrations, exposed_presence focus.select('#tooltip-time').text('x = ' + time_format(d.hour)); focus.select('#tooltip-concentration').text('y = ' + d.concentration.toFixed(2)); } -} +} \ No newline at end of file diff --git a/cara/apps/calculator/templates/base/calculator.report.html.j2 b/cara/apps/calculator/templates/base/calculator.report.html.j2 index d45a089a..8a36f52b 100644 --- a/cara/apps/calculator/templates/base/calculator.report.html.j2 +++ b/cara/apps/calculator/templates/base/calculator.report.html.j2 @@ -8,7 +8,6 @@ - @@ -18,309 +17,419 @@ {% block report_header %} -
- -

Report

+
+ +
+

CARA - CALCULATOR REPORT

+

Created {{ creation_date }} using CARA calculator version v{{ form.calculator_version }}

+
+ + {# To be replaced by "Generate PDF" #} +
-

Created {{ creation_date }} using CARA calculator version v{{ form.calculator_version }}


- {% endblock report_header %} - -{% block report_preamble %} - -{% endblock report_preamble %} - -{% block simulation_overview %} -

Simulation:

- -

Simulation Name: {{ form.simulation_name }}

-

Room Number: {{ form.room_number }}

- -

Input data:

-