88import pandas as pd
99
1010from . import report as r
11- from .utils import create_folder , is_url , sort_imports
11+ from .utils import create_folder , get_relative_file_path , is_url , sort_imports
1212
1313
1414class QuartoReportView (r .ReportView ):
@@ -365,6 +365,7 @@ def _create_yaml_header(self) -> str:
365365 r .ReportType .PDF : """
366366 pdf:
367367 toc: false
368+ fig-align: center
368369 margin:
369370 - bottom=40mm
370371 include-in-header:
@@ -568,13 +569,13 @@ def _generate_plot_content(self, plot) -> List[str]:
568569 try :
569570 if plot .plot_type == r .PlotType .STATIC :
570571 plot_content .append (
571- self ._generate_image_content (plot .file_path , width = 950 )
572+ self ._generate_image_content (plot .file_path , width = "90%" )
572573 )
573574 elif plot .plot_type == r .PlotType .PLOTLY :
574575 plot_content .append (self ._generate_plot_code (plot ))
575576 if self .is_report_static :
576577 plot_content .append (
577- f"""fig_plotly.write_image("{ static_plot_path .resolve ( ).as_posix ()} ")\n ```\n """
578+ f"""fig_plotly.write_image("{ static_plot_path .relative_to ( "quarto_report" ).as_posix ()} ")\n ```\n """
578579 )
579580 plot_content .append (self ._generate_image_content (static_plot_path ))
580581 else :
@@ -583,7 +584,7 @@ def _generate_plot_content(self, plot) -> List[str]:
583584 plot_content .append (self ._generate_plot_code (plot ))
584585 if self .is_report_static :
585586 plot_content .append (
586- f"""fig_altair.save("{ static_plot_path .resolve ( ).as_posix ()} ")\n ```\n """
587+ f"""fig_altair.save("{ static_plot_path .relative_to ( "quarto_report" ).as_posix ()} ")\n ```\n """
587588 )
588589 plot_content .append (self ._generate_image_content (static_plot_path ))
589590 else :
@@ -655,8 +656,9 @@ def _generate_plot_code(self, plot, output_file="") -> str:
655656response.raise_for_status()
656657plot_json = response.text\n """
657658 else : # If it's a local file
659+ plot_rel_path = get_relative_file_path (plot .file_path , base_path = ".." )
658660 plot_code += f"""
659- with open('{ ( Path ( ".." ) / plot . file_path ) .as_posix ()} ', 'r') as plot_file:
661+ with open('{ plot_rel_path .as_posix ()} ', 'r') as plot_file:
660662 plot_json = json.load(plot_file)\n """
661663 # Add specific code for each visualization tool
662664 if plot .plot_type == r .PlotType .PLOTLY :
@@ -669,13 +671,13 @@ def _generate_plot_code(self, plot, output_file="") -> str:
669671plot_json_str = json.dumps(plot_json)\n
670672# Create the plotly plot
671673fig_plotly = pio.from_json(plot_json_str)
672- fig_plotly.update_layout(width=950, height=500 )\n """
674+ fig_plotly.update_layout(autosize=False, width=950, height=400, margin=dict(b=50, t=50, l=50, r=50) )\n """
673675 elif plot .plot_type == r .PlotType .ALTAIR :
674676 plot_code += """
675677# Convert JSON to string
676678plot_json_str = json.dumps(plot_json)\n
677679# Create the plotly plot
678- fig_altair = alt.Chart.from_json(plot_json_str).properties(width=900, height=400 )\n """
680+ fig_altair = alt.Chart.from_json(plot_json_str).properties(width=900, height=370 )\n """
679681 elif plot .plot_type == r .PlotType .INTERACTIVE_NETWORK :
680682 # Generate the HTML embedding for interactive networks
681683 if is_url (plot .file_path ) and plot .file_path .endswith (".html" ):
@@ -734,16 +736,17 @@ def _generate_dataframe_content(self, dataframe) -> List[str]:
734736 )
735737
736738 # Build the file path (URL or local file)
737- file_path = (
738- dataframe .file_path
739- if is_url (dataframe .file_path )
740- else Path (".." ) / dataframe .file_path
741- )
739+ if is_url (dataframe .file_path ):
740+ df_file_path = dataframe .file_path
741+ else :
742+ df_file_path = get_relative_file_path (
743+ dataframe .file_path , base_path = ".."
744+ )
742745
743746 # Load the DataFrame using the correct function
744747 read_function = read_function_mapping [file_extension ]
745748 dataframe_content .append (
746- f"""df = pd.{ read_function .__name__ } ('{ file_path .as_posix ()} ')\n """
749+ f"""df = pd.{ read_function .__name__ } ('{ df_file_path .as_posix ()} ')\n """
747750 )
748751
749752 # Display the dataframe
@@ -798,9 +801,10 @@ def _generate_markdown_content(self, markdown) -> List[str]:
798801markdown_content = response.text\n """
799802 )
800803 else : # If it's a local file
804+ md_rel_path = get_relative_file_path (markdown .file_path , base_path = ".." )
801805 markdown_content .append (
802806 f"""
803- with open('{ ( Path ( ".." ) / markdown . file_path ) .as_posix ()} ', 'r') as markdown_file:
807+ with open('{ md_rel_path .as_posix ()} ', 'r') as markdown_file:
804808 markdown_content = markdown_file.read()\n """
805809 )
806810
@@ -822,6 +826,39 @@ def _generate_markdown_content(self, markdown) -> List[str]:
822826 )
823827 return markdown_content
824828
829+ def _show_dataframe (self , dataframe ) -> List [str ]:
830+ """
831+ Appends either a static image or an interactive representation of a DataFrame to the content list.
832+
833+ Parameters
834+ ----------
835+ dataframe : DataFrame
836+ The DataFrame object containing the data to display.
837+
838+ Returns
839+ -------
840+ list : List[str]
841+ The list of content lines for the DataFrame.
842+ """
843+ dataframe_content = []
844+ if self .is_report_static :
845+ # Generate path for the DataFrame image
846+ df_image = (
847+ Path (self .static_dir ) / f"{ dataframe .title .replace (' ' , '_' )} .png"
848+ )
849+ dataframe_content .append (
850+ f"df.dfi.export('{ Path (df_image ).relative_to ('quarto_report' ).as_posix ()} ', max_rows=10, max_cols=5, table_conversion='matplotlib')\n ```\n "
851+ )
852+ # Use helper method to add centered image content
853+ dataframe_content .append (self ._generate_image_content (df_image ))
854+ else :
855+ # Append code to display the DataFrame interactively
856+ dataframe_content .append (
857+ """show(df, classes="display nowrap compact", lengthMenu=[3, 5, 10])\n ```\n """
858+ )
859+
860+ return dataframe_content
861+
825862 def _generate_html_content (self , html ) -> List [str ]:
826863 """
827864 Adds an HTML component to the report.
@@ -843,14 +880,13 @@ def _generate_html_content(self, html) -> List[str]:
843880
844881 try :
845882 # Embed the HTML in an iframe
846- iframe_src = (
847- html .file_path
848- if is_url (html .file_path )
849- else Path (".." ) / html .file_path
850- )
883+ if is_url (html .file_path ):
884+ html_file_path = html .file_path
885+ else :
886+ html_file_path = get_relative_file_path (html .file_path , base_path = ".." )
851887 iframe_code = f"""
852888<div style="text-align: center;">
853- <iframe src="{ iframe_src } " alt="{ html .title } " width="800px " height="630px "></iframe>
889+ <iframe src="{ html_file_path . as_posix () } " alt="{ html .title } " width="950px " height="530px "></iframe>
854890</div>\n """
855891 html_content .append (iframe_code )
856892
@@ -866,7 +902,7 @@ def _generate_html_content(self, html) -> List[str]:
866902 return html_content
867903
868904 def _generate_image_content (
869- self , image_path : str , alt_text : str = "" , width : int = 650 , height : int = 400
905+ self , image_path : str , alt_text : str = "" , width : str = "90%"
870906 ) -> str :
871907 """
872908 Adds an image to the content list in an HTML format with a specified width and height.
@@ -889,47 +925,10 @@ def _generate_image_content(
889925 """
890926 if is_url (image_path ):
891927 src = image_path
892- return (
893- f"""{{fig-alt={ alt_text } width={ width } height={ height } }}\n """
894- )
895928 else :
896- src = Path (image_path ).resolve ()
897- return (
898- f"""{{fig-alt={ alt_text } width={ width } height={ height } }}\n """
899- )
900-
901- def _show_dataframe (self , dataframe ) -> List [str ]:
902- """
903- Appends either a static image or an interactive representation of a DataFrame to the content list.
904-
905- Parameters
906- ----------
907- dataframe : DataFrame
908- The DataFrame object containing the data to display.
929+ src = get_relative_file_path (image_path , base_path = ".." ).as_posix ()
909930
910- Returns
911- -------
912- list : List[str]
913- The list of content lines for the DataFrame.
914- """
915- dataframe_content = []
916- if self .is_report_static :
917- # Generate path for the DataFrame image
918- df_image = (
919- Path (self .static_dir ) / f"{ dataframe .title .replace (' ' , '_' )} .png"
920- )
921- dataframe_content .append (
922- f"df.dfi.export('{ Path (df_image ).resolve ().as_posix ()} ', max_rows=10, max_cols=5, table_conversion='matplotlib')\n ```\n "
923- )
924- # Use helper method to add centered image content
925- dataframe_content .append (self ._generate_image_content (df_image ))
926- else :
927- # Append code to display the DataFrame interactively
928- dataframe_content .append (
929- """show(df, classes="display nowrap compact", lengthMenu=[3, 5, 10])\n ```\n """
930- )
931-
932- return dataframe_content
931+ return f"""{{fig-alt={ alt_text } width={ width } }}\n """
933932
934933 def _generate_component_imports (self , component : r .Component ) -> List [str ]:
935934 """
0 commit comments