@@ -46,21 +46,51 @@ def render_html(
4646 dataframe : pd .DataFrame ,
4747 table_id : str ,
4848 orderable_columns : list [str ] | None = None ,
49+ max_columns : int | None = None ,
4950) -> str :
5051 """Render a pandas DataFrame to HTML with specific styling."""
5152 orderable_columns = orderable_columns or []
5253 classes = "dataframe table table-striped table-hover"
5354 table_html_parts = [f'<table border="1" class="{ classes } " id="{ table_id } ">' ]
54- table_html_parts .append (_render_table_header (dataframe , orderable_columns ))
55- table_html_parts .append (_render_table_body (dataframe ))
55+
56+ # Handle column truncation
57+ columns = list (dataframe .columns )
58+ if max_columns is not None and max_columns > 0 and len (columns ) > max_columns :
59+ half = max_columns // 2
60+ left_columns = columns [:half ]
61+ # Ensure we don't take more than available if half is 0 or calculation is weird,
62+ # but typical case is safe.
63+ right_count = max_columns - half
64+ right_columns = columns [- right_count :] if right_count > 0 else []
65+ show_ellipsis = True
66+ else :
67+ left_columns = columns
68+ right_columns = []
69+ show_ellipsis = False
70+
71+ table_html_parts .append (
72+ _render_table_header (
73+ dataframe , orderable_columns , left_columns , right_columns , show_ellipsis
74+ )
75+ )
76+ table_html_parts .append (
77+ _render_table_body (dataframe , left_columns , right_columns , show_ellipsis )
78+ )
5679 table_html_parts .append ("</table>" )
5780 return "" .join (table_html_parts )
5881
5982
60- def _render_table_header (dataframe : pd .DataFrame , orderable_columns : list [str ]) -> str :
83+ def _render_table_header (
84+ dataframe : pd .DataFrame ,
85+ orderable_columns : list [str ],
86+ left_columns : list [Any ],
87+ right_columns : list [Any ],
88+ show_ellipsis : bool ,
89+ ) -> str :
6190 """Render the header of the HTML table."""
6291 header_parts = [" <thead>" , " <tr>" ]
63- for col in dataframe .columns :
92+
93+ def render_col_header (col ):
6494 th_classes = []
6595 if col in orderable_columns :
6696 th_classes .append ("sortable" )
@@ -69,19 +99,38 @@ def _render_table_header(dataframe: pd.DataFrame, orderable_columns: list[str])
6999 f' <th { class_str } ><div class="bf-header-content">'
70100 f"{ html .escape (str (col ))} </div></th>"
71101 )
102+
103+ for col in left_columns :
104+ render_col_header (col )
105+
106+ if show_ellipsis :
107+ header_parts .append (
108+ ' <th><div class="bf-header-content" style="cursor: default;">...</div></th>'
109+ )
110+
111+ for col in right_columns :
112+ render_col_header (col )
113+
72114 header_parts .extend ([" </tr>" , " </thead>" ])
73115 return "\n " .join (header_parts )
74116
75117
76- def _render_table_body (dataframe : pd .DataFrame ) -> str :
118+ def _render_table_body (
119+ dataframe : pd .DataFrame ,
120+ left_columns : list [Any ],
121+ right_columns : list [Any ],
122+ show_ellipsis : bool ,
123+ ) -> str :
77124 """Render the body of the HTML table."""
78125 body_parts = [" <tbody>" ]
79126 precision = options .display .precision
80127
81128 for i in range (len (dataframe )):
82129 body_parts .append (" <tr>" )
83130 row = dataframe .iloc [i ]
84- for col_name , value in row .items ():
131+
132+ def render_col_cell (col_name ):
133+ value = row [col_name ]
85134 dtype = dataframe .dtypes .loc [col_name ] # type: ignore
86135 align = "right" if _is_dtype_numeric (dtype ) else "left"
87136
@@ -101,6 +150,17 @@ def _render_table_body(dataframe: pd.DataFrame) -> str:
101150 f' <td class="cell-align-{ align } ">'
102151 f"{ html .escape (cell_content )} </td>"
103152 )
153+
154+ for col in left_columns :
155+ render_col_cell (col )
156+
157+ if show_ellipsis :
158+ # Ellipsis cell
159+ body_parts .append (' <td class="cell-align-center">...</td>' )
160+
161+ for col in right_columns :
162+ render_col_cell (col )
163+
104164 body_parts .append (" </tr>" )
105165 body_parts .append (" </tbody>" )
106166 return "\n " .join (body_parts )
0 commit comments