Skip to content

Commit 214594c

Browse files
separate data from adoc in figures
1 parent 0f4b255 commit 214594c

File tree

11 files changed

+137
-87
lines changed

11 files changed

+137
-87
lines changed
Lines changed: 84 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -1,54 +1,91 @@
1+
import os, zipfile
2+
from typing import List, Dict, Union
3+
import pandas as pd
4+
from uuid import uuid4
5+
6+
from feelpp.benchmarking.json_report.figures.transformationFactory import TransformationFactory
17
from feelpp.benchmarking.json_report.figures.figureFactory import FigureFactory
28
from feelpp.benchmarking.json_report.figures.schemas.plot import Plot
3-
from typing import List, Dict, Union
49

510
class Controller:
6-
""" Controller component , it orchestrates the model with the view"""
7-
def __init__(self, df, plots_config: Union[List[Dict],Dict,Plot,List[Plot]]):
11+
def __init__(self, data:pd.DataFrame, plot_config: Union[Dict,Plot]):
812
"""
9-
Args:
10-
model (pd.DataFrame): The atomic report model component
11-
view (AtomicReportView): The atomic report view component
1213
"""
13-
self.df = df
14-
if isinstance(plots_config,Plot):
15-
self.plots_config = [plots_config]
16-
elif isinstance(plots_config,Dict):
17-
self.plots_config = [Plot(**plots_config)]
18-
elif isinstance(plots_config,List):
19-
if all(isinstance(d,Plot) for d in plots_config):
20-
self.plots_config = plots_config
21-
else:
22-
self.plots_config = [Plot(**d) for d in plots_config]
14+
self.id = uuid4().hex
15+
if not isinstance(data,pd.DataFrame):
16+
raise NotImplementedError(f"Data type {type(data)} not supported for Figures")
17+
18+
if isinstance(plot_config,Plot):
19+
self.plot_config = plot_config
20+
elif isinstance(plot_config,Dict):
21+
self.plot_config = Plot(**plot_config)
2322
else:
24-
raise TypeError(f"plots_config must be a Dict or List of Dicts, got {type(plots_config)}")
25-
self.figures = [FigureFactory.create(plot_config) for plot_config in self.plots_config]
26-
27-
def generateAll(self):
28-
if self.df is None or self.df.empty:
29-
return []
30-
return [
31-
self.generateFigure(figure,plot_config.plot_types)
32-
for figure,plot_config in zip(self.figures,self.plots_config)
33-
]
34-
35-
def generateFigure(self,figure,plot_types):
36-
return {
37-
"plot_types": plot_types,
38-
"subfigures": [self.generateSubfigure(subfigure) for subfigure in figure]
39-
}
40-
41-
def generateSubfigure(self, subfigure):
42-
return {
43-
"exports": [
44-
{ "display_text":"CSV", "data":[
45-
{ "format":"csv", "prefix":"data","content":subfigure.createCsvs(self.df)}
46-
]},
47-
{ "display_text":"LaTeX", "data":[
48-
{"format":"tex","content":[{ "data":subfigure.createTex(self.df), "title":"figures" }]},
49-
{"format":"csv","content":subfigure.createCsvs(self.df)}
50-
51-
]},
52-
],
53-
"html": subfigure.createFigureHtml(self.df)
54-
}
23+
raise TypeError(f"plot_config must be a Dict or a Plot model, got {type(plot_config)}")
24+
25+
self.data = data #TransformationFactory.create(self.plot_config).calculate(data)
26+
27+
self.figures = FigureFactory.create(self.plot_config)
28+
29+
30+
def dumpFigureJsons(self,outdir:str = ".") -> str:
31+
""" Returns the path relative to outdir """
32+
plotly_figs = [fig.createFigure(self.data) for fig in self.figures]
33+
filepaths = []
34+
for plotly_fig,plot_type in zip(plotly_figs,self.plot_config.plot_types):
35+
fig_relpath = os.path.join(self.id,f"{plot_type}.json")
36+
filepath = os.path.join(outdir,fig_relpath)
37+
38+
os.makedirs(os.path.dirname(filepath),exist_ok=True)
39+
40+
with open(filepath,"w") as f:
41+
f.write(plotly_fig.to_json())
42+
43+
filepaths.append(fig_relpath)
44+
return filepaths
45+
46+
47+
def dumpFigureCsvs(self, outdir:str = ".") -> str:
48+
""" Returns the path relative to outdir """
49+
filepaths = []
50+
for figure,plot_type in zip(self.figures,self.plot_config.plot_types):
51+
fig_relpath = os.path.join(self.id,f"{plot_type}.zip")
52+
filepath = os.path.join(outdir,fig_relpath)
53+
54+
os.makedirs(os.path.dirname(filepath), exist_ok=True)
55+
56+
csvs = figure.createCsvs(self.data)
57+
with zipfile.ZipFile( file=filepath, mode="w", compression=zipfile.ZIP_DEFLATED, compresslevel=9) as zip_archive:
58+
for csv in csvs:
59+
zip_archive.writestr(zinfo_or_arcname=f"{csv["title"]}.csv",data=csv["data"])
60+
61+
filepaths.append(fig_relpath)
62+
return filepaths
63+
64+
# def generateAll(self):
65+
# if self.df is None or self.df.empty:
66+
# return []
67+
# return [
68+
# self.generateFigure(figure,plot_config.plot_types)
69+
# for figure,plot_config in zip(self.figures,self.plots_config)
70+
# ]
71+
72+
# def generateFigure(self,figure,plot_types):
73+
# return {
74+
# "plot_types": plot_types,
75+
# "subfigures": [self.generateSubfigure(subfigure) for subfigure in figure]
76+
# }
77+
78+
# def generateSubfigure(self, subfigure):
79+
# return {
80+
# "exports": [
81+
# { "display_text":"CSV", "data":[
82+
# { "format":"csv", "prefix":"data","content":subfigure.createCsvs(self.df)}
83+
# ]},
84+
# { "display_text":"LaTeX", "data":[
85+
# {"format":"tex","content":[{ "data":subfigure.createTex(self.df), "title":"figures" }]},
86+
# {"format":"csv","content":subfigure.createCsvs(self.df)}
87+
88+
# ]},
89+
# ],
90+
# "html": subfigure.createFigureHtml(self.df)
91+
# }

src/feelpp/benchmarking/json_report/renderer.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ def initRenderer( self) -> TemplateRenderer:
4545
template_path, template_filename = self.getTemplatePath( )
4646
renderer = TemplateRenderer( template_paths=template_path, template_filename=template_filename )
4747
renderer.env.globals.update( {
48+
"zip":zip,
4849
"FiguresController":FiguresController,
4950
"TableController":TableController,
5051
"TextController":TextController

src/feelpp/benchmarking/json_report/templates/adoc/json2adoc_report.adoc.j2

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,11 @@
66
:docdatetime: {{ report.datetime }}
77
{% endif %}
88

9-
{% import "macros/section.adoc.j2" as section %}
109

11-
{{ section.render(report, report_data, 1) }}
10+
{% set context = {
11+
"attachments_dirpath": attachments_dirpath,
12+
"attachments_base_url": attachments_base_url
13+
} %}
14+
15+
{% import "macros/section.adoc.j2" as section %}
16+
{{ section.render(report, report_data, 1, context=context) }}

src/feelpp/benchmarking/json_report/templates/adoc/macros/grid.adoc.j2

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
{% import "macros/table.adoc.j2" as table %}
66
{% import "macros/itemize.adoc.j2" as itemize %}
77

8-
{% macro render(gridNode,report_data) %}
8+
{% macro render(gridNode,report_data, context={}) %}
99
{% if gridNode.id %}
1010
[[{{gridNode.id}}]]
1111
{% endif %}
@@ -19,17 +19,17 @@
1919
:figure-caption!:
2020
{%for node in gridNode.contents%}
2121
{% if node.type == "image" %}
22-
{{ image.render(node,report_data.get(node.ref), make_block=False) }}
22+
{{ image.render(node,report_data.get(node.ref), make_block=False, context=context) }}
2323
{% elif node.type == "plot" %}
24-
{{ plot.render(node,report_data.get(node.ref), make_block=False) }}
24+
{{ plot.render(node,report_data.get(node.ref), make_block=False, context=context) }}
2525
{% elif node.type == "latex" %}
26-
{{ latex.render(node,report_data.get(node.ref)) }}
26+
{{ latex.render(node,report_data.get(node.ref), context=context) }}
2727
{% elif node.type == "text" %}
28-
{{ text.render(node,report_data.get(node.ref)) }}
28+
{{ text.render(node,report_data.get(node.ref), context=context) }}
2929
{% elif node.type == "table" %}
30-
{{ table.render(node,report_data.get(node.ref)) }}
30+
{{ table.render(node,report_data.get(node.ref), context=context) }}
3131
{% elif node.type == "itemize" %}
32-
{{ itemize.render(node,report_data.get(node.ref)) }}
32+
{{ itemize.render(node,report_data.get(node.ref), context=context) }}
3333
{% endif %}
3434
{% endfor %}
3535
:figure-caption: Figure

src/feelpp/benchmarking/json_report/templates/adoc/macros/image.adoc.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{% macro render(imageNode,data,make_block = True) %}
1+
{% macro render(imageNode,data,make_block = True, context={}) %}
22
{% set src = imageNode.src %}
33
{% set alt = imageNode.alt or imageNode.caption or "" %}
44
{% set styles = imageNode.style | join(' ')%}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
{% import "macros/text.adoc.j2" as text %}
22

3-
{% macro render(listNode,data) %}
3+
{% macro render(listNode,data,context={}) %}
44

55
{% if listNode.id %}
66
[[{{listNode.id}}]]
77
{% endif %}
88
{% for item in listNode.items %}
9-
- {{text.render(item,data)}}
9+
- {{text.render(item,data,context=context)}}
1010
{% endfor %}
1111

1212
{% endmacro %}

src/feelpp/benchmarking/json_report/templates/adoc/macros/latex.adoc.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{% macro render(latexNode,data) %}
1+
{% macro render(latexNode,data,context={}) %}
22

33
{% if latexNode.id %}
44
[[{{latexNode.id}}]]

src/feelpp/benchmarking/json_report/templates/adoc/macros/plot.adoc.j2

Lines changed: 28 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{% macro render(plotNode,data, make_block=True) %}
1+
{% macro render(plotNode,data, make_block=True, context={}) %}
22

33

44
{% if plotNode.id %}
@@ -15,38 +15,45 @@
1515
{% endif %}
1616
++++
1717

18-
{% for figure in FiguresController(data.get(plotNode.ref),plotNode.plot).generateAll() %}
18+
{% set figure_ctrl = FiguresController(data.get(plotNode.ref),plotNode.plot) %}
19+
{% set figure_json_paths = figure_ctrl.dumpFigureJsons(context.attachments_dirpath) %}
20+
{% set figure_csv_paths = figure_ctrl.dumpFigureCsvs(context.attachments_dirpath) %}
1921
<div class='figure-container'>
20-
{% if figure.plot_types | length > 1%}
22+
{% if figure_ctrl.plot_config.plot_types | length > 1%}
2123
<div class='tabs-container'>
22-
{% for plot_type in figure.plot_types %}
24+
{% for plot_type in figure_ctrl.plot_config.plot_types %}
2325
{% set plot_type_i = loop.index %}
2426
<button class='figure-tab' onclick='switchTab(this, {{plot_type_i}})'>{{plot_type}}</button>
2527
{% endfor %}
2628
</div>
2729
{% endif %}
2830

29-
{% for subfigure in figure.subfigures %}
30-
<div class="subfigure-container {% if loop.first %}active{% else %}inactive{% endif %}" data-subfigure="{{loop.index}}">
31-
{{subfigure.html}}
32-
33-
<div class='export-container'>
34-
{% for export in subfigure.exports %}
35-
<button onclick='downloadData({{export.data | tojson | stripquotes}},"download.zip")' >
36-
{{export.display_text}}
37-
</button>
38-
{% endfor %}
39-
</div>
40-
31+
{% for subfigure_json_path, subfigure_csv_path in zip(figure_json_paths,figure_csv_paths) %}
32+
<div class="subfigure-container {% if loop.first %}active{% else %}inactive{% endif %}" data-subfigure="{{loop.index}}">
33+
<div id="graph-div-{{figure_ctrl.id}}-{{loop.index}}"> </div>
4134
</div>
42-
{% endfor %}
43-
44-
{%if plotNode.caption and make_block==False %}
45-
<div class='plotly-figure-caption title'>{{plotNode.caption}}</div>
46-
{% endif %}
35+
<div class='export-container'>
36+
<a href='{% if context.attachments_base_url %}{{context.attachments_base_url}}/{{subfigure_csv_path}}{% else %}{{context.attachments_dirpath}}/{{subfigure_csv_path}}{%endif%}' download>CSV<a/>
37+
</div>
38+
{% endfor %}
4739
</div>
4840

41+
42+
<script>
43+
{% for subfigure_json_path in figure_json_paths %}
44+
fetch('{% if context.attachments_base_url %}{{context.attachments_base_url}}/{{subfigure_json_path}}{% else %}{{context.attachments_dirpath}}/{{subfigure_json_path}}{%endif%}')
45+
.then(response => response.json())
46+
.then(figure_json => {
47+
Plotly.newPlot('graph-div-{{figure_ctrl.id}}-{{loop.index}}',figure_json);
48+
})
49+
.catch(err => console.error(err));
4950
{% endfor %}
51+
</script>
52+
53+
{%if plotNode.caption and make_block==False %}
54+
<div class='plotly-figure-caption title'>{{plotNode.caption}}</div>
55+
{% endif %}
56+
5057

5158
++++
5259
{% if make_block %}

src/feelpp/benchmarking/json_report/templates/adoc/macros/section.adoc.j2

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
"itemize": itemize.render
1616
} %}
1717

18-
{% macro render(sectionNode, report_data, level=1) %}
18+
{% macro render(sectionNode, report_data, level=1, context={}) %}
1919

2020
{% if sectionNode.id %}
2121
[[{{sectionNode.id}}]]
@@ -26,13 +26,13 @@
2626

2727
{% for node in sectionNode.contents %}
2828
{% if node.type == "section" %}
29-
{{ render(node, report_data, level + 1) }}
29+
{{ render(node, report_data, level + 1,context=context) }}
3030
{% elif node.type == "grid" %}
31-
{{ grid.render(node, report_data ) }}
31+
{{ grid.render(node, report_data,context=context) }}
3232
{% else %}
3333
{% set handler = handlers.get(node.type) %}
3434
{% if handler %}
35-
{{ handler(node,report_data.get(node.ref)) }}
35+
{{ handler(node,report_data.get(node.ref),context=context) }}
3636
{% endif %}
3737
{% endif %}
3838
{% endfor %}

src/feelpp/benchmarking/json_report/templates/adoc/macros/table.adoc.j2

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
{% macro render(tableNode, data) %}
1+
{% macro render(tableNode, data, context={}) %}
22

33
{%set table_controller = TableController(data.get(tableNode.ref),tableNode.layout, tableNode.style) %}
44
{%set table = table_controller.generate() %}

0 commit comments

Comments
 (0)