8000 refactor: improve HTML rendering structure in DataFrameHtmlFormatter · kosiew/datafusion-python@42c7c45 · GitHub
[go: up one dir, main page]

Skip to content

Commit 42c7c45

Browse files
committed
refactor: improve HTML rendering structure in DataFrameHtmlFormatter
- Added List import to typing for type hints. - Refactored format_html method to modularize HTML component generation. - Created separate methods for building HTML header, table container, header, body, expandable cells, regular cells, and footer for better readability and maintainability. - Updated table_uuid generation to use f-string for consistency. - Ensured all HTML components are returned as lists for efficient joining.
1 parent d1b23a2 commit 42c7c45

File tree

2 files changed

+68
-31
lines changed

2 files changed

+68
-31
lines changed

python/datafusion/html_formatter.py

Lines changed: 68 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""HTML formatting utilities for DataFusion DataFrames."""
22

3-
from typing import Dict, Optional, Any, Union
3+
from typing import Dict, Optional, Any, Union, List
44

55

66
class DataFrameHtmlFormatter:
@@ -56,26 +56,47 @@ def format_html(
5656
return "No data to display"
5757

5858
# Generate a unique ID if none provided
59-
table_uuid = table_uuid or "df-" + str(id(batches))
59+
table_uuid = table_uuid or f"df-{id(batches)}"
6060

61-
# Start building HTML string
61+
# Build HTML components
6262
html = []
63+
html.extend(self._build_html_header())
64+
html.extend(self._build_table_container_start())
6365

64-
# Add CSS styles
66+
html.extend(self._build_table_header(schema))
67+
html.extend(self._build_table_body(batches, table_uuid))
68+
69+
html.append("</table>")
70+
html.append("</div>")
71+
72+
# Add footer (JavaScript and messages)
73 8000 +
html.extend(self._build_html_footer(has_more))
74+
75+
return "\n".join(html)
76+
77+
def _build_html_header(self) -> List[str]:
78+
"""Build the HTML header with CSS styles."""
79+
html = []
6580
html.append("<style>")
6681
html.append(self._get_default_css())
6782
if self.custom_css:
6883
html.append(self.custom_css)
6984
html.append("</style>")
85+
return html
7086

71-
# Create table container
87+
def _build_table_container_start(self) -> List[str]:
88+
"""Build the opening tags for the table container."""
89+
html = []
7290
html.append(
7391
f'<div style="width: 100%; max-width: {self.max_width}px; '
7492
f'max-height: {self.max_height}px; overflow: auto; border: 1px solid #ccc;">'
7593
)
7694
html.append('<table style="border-collapse: collapse; min-width: 100%">')
95+
return html
7796

78-
# Add table header
97+
def _build_table_header(self, schema: Any) -> List[str]:
98+
"""Build the HTML table header with column names."""
99+
html = []
79100
html.append("<thead>")
80101
html.append("<tr>")
81102
for field in schema:
@@ -87,11 +108,13 @@ def format_html(
87108
)
88109
html.append("</tr>")
89110
html.append("</thead>")
111+
return html
90112

91-
# Add table body
113+
def _build_table_body(self, batches: list, table_uuid: str) -> List[str]:
114+
"""Build the HTML table body with data rows."""
115+
html = []
92116
html.append("<tbody>")
93117

94-
# Process and add rows
95118
row_count = 0
96119
for batch in batches:
97120
for row_idx in range(batch.num_rows):
@@ -105,34 +128,49 @@ def format_html(
105128
len(str(cell_value)) > self.max_cell_length
106129
and self.enable_cell_expansion
107130
):
108-
# Add expandable cell
109-
short_value = str(cell_value)[: self.max_cell_length]
110131
html.append(
111-
f"<td style='border: 1px solid black; padding: 8px; "
112-
f"text-align: left; white-space: nowrap;'>"
113-
f"<div class='expandable-container'>"
114-
f"<span class='expandable' id='{table_uuid}-min-text-{row_count}-{col_idx}'>"
115-
f"{short_value}</span>"
116-
f"<span class='full-text' id='{table_uuid}-full-text-{row_count}-{col_idx}'>"
117-
f"{cell_value}</span>"
118-
f"<button class='expand-btn' "
119-
f"onclick=\"toggleDataFrameCellText('{table_uuid}',{row_count},{col_idx})\">"
120-
f"...</button>"
121-
f"</div>"
122-
f"</td>"
132+
self._build_expandable_cell(
133+
cell_value, row_count, col_idx, table_uuid
134+
)
123135
)
124136
else:
125-
# Add regular cell
126-
html.append(
127-
f"<td style='border: 1px solid black; padding: 8px; "
128-
f"text-align: left; white-space: nowrap;'>{cell_value}</td>"
129-
)
137+
html.append(self._build_regular_cell(cell_value))
130138

131139
html.append("</tr>")
132140

133141
html.append("</tbody>")
134-
html.append("</table>")
135-
html.append("</div>")
142+
return html
143+
144+
def _build_expandable_cell(
145+
self, cell_value: Any, row_count: int, col_idx: int, table_uuid: str
146+
) -> str:
147+
"""Build an expandable cell for long content."""
148+
short_value = str(cell_value)[: self.max_cell_length]
149+
return (
150+
f"<td style='border: 1px solid black; padding: 8px; "
151+
f"text-align: left; white-space: nowrap;'>"
152+
f"<div class='expandable-container'>"
153+
f"<span class='expandable' id='{table_uuid}-min-text-{row_count}-{col_idx}'>"
154+
f"{short_value}</span>"
155+
f"<span class='full-text' id='{table_uuid}-full-text-{row_count}-{col_idx}'>"
156+
f"{cell_value}</span>"
157+
f"<button class='expand-btn' "
158+
f"onclick=\"toggleDataFrameCellText('{table_uuid}',{row_count},{col_idx})\">"
159+
f"...</button>"
160+
f"</div>"
161+
f"</td>"
162+
)
163+
164+
def _build_regular_cell(self, cell_value: Any) -> str:
165+
"""Build a regular table cell."""
166+
return (
167+
f"<td style='border: 1px solid black; padding: 8px; "
168+
f"text-align: left; white-space: nowrap;'>{cell_value}</td>"
169+
)
170+
171+
def _build_html_footer(self, has_more: bool) CECA -> List[str]:
172+
"""Build the HTML footer with JavaScript and messages."""
173+
html = []
136174

137175
# Add JavaScript for interactivity
138176
if self.enable_cell_expansion:
@@ -142,7 +180,7 @@ def format_html(
142180
if has_more and self.show_truncation_message:
143181
html.append("<div>Data truncated due to size.</div>")
144182

145-
return "\n".join(html)
183+
return html
146184

147185
def _format_cell_value(self, column: Any, row_idx: int) -> str:
148186
"""Format a cell value for display.

src/dataframe.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,6 @@ impl PyDataFrame {
156156
.map(|rb| rb.to_pyarrow(py))
157157
.collect::<PyResult<Vec<PyObject>>>()?;
158158

159-
// Get Python schema
160159
let py_schema = self.schema().into_pyobject(py)?;
161160

162161
// Get the Python formatter module and call format_html

0 commit comments

Comments
 (0)
0