Skip to content

Add table() method for formatted HTML table visualization#1083

Open
nitininhouse wants to merge 1 commit intofossasia:masterfrom
nitininhouse:feature/table
Open

Add table() method for formatted HTML table visualization#1083
nitininhouse wants to merge 1 commit intofossasia:masterfrom
nitininhouse:feature/table

Conversation

@nitininhouse
Copy link

@nitininhouse nitininhouse commented Mar 23, 2026

Description

Added table() method to Visdom for displaying formatted HTML tables. Renders structured data with styled headers, alternating row colors, hover effects, and monospace font for clean presentation.

Motivation and Context

Tables are essential for displaying structured training metrics, results summaries, and comparison data. This feature eliminates manual HTML formatting and provides a consistent, visually appealing way to visualize tabular data within Visdom.

closes #1081

How Has This Been Tested?

Tested with sample training data:

viz.table(
    headers=['Epoch', 'Loss', 'Accuracy'],
    data=[[1, 0.45, 0.92], [2, 0.32, 0.94], [3, 0.21, 0.96]],
    opts={'title': 'Training Results'}
)

Copilot AI review requested due to automatic review settings March 23, 2026 04:49
Copy link
Contributor

@sourcery-ai sourcery-ai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry @nitininhouse, you have reached your weekly rate limit of 500000 diff characters.

Please try again later or upgrade to continue using Sourcery

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a new table() helper to the Visdom Python client to render structured data as a styled HTML table via the existing text() endpoint.

Changes:

  • Introduces Visdom.table(headers, data, ...) to generate HTML <table> markup from headers + rows
  • Adds basic table styling (header background, alternating row colors, monospace font)
  • Performs basic input validation and sets a default window title

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +977 to +981
header_html = ''.join(
'<th style="background:#4a90d9; color:white; '
'padding:8px 12px; text-align:left;">%s</th>' % str(h)
for h in headers
)
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Header and cell values are interpolated into HTML without escaping. If any values contain HTML (e.g., <script>), this will be rendered/executed in the Visdom UI (XSS risk). Escape h and cell with html.escape(str(...), quote=True) (or an equivalent escaping utility already used in the project) before inserting into the <th>/<td> markup.

Copilot uses AI. Check for mistakes.
Comment on lines +987 to +991
cells = ''.join(
'<td style="padding:6px 12px; '
'border-bottom:1px solid #ddd;">%s</td>' % str(cell)
for cell in row
)
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Header and cell values are interpolated into HTML without escaping. If any values contain HTML (e.g., <script>), this will be rendered/executed in the Visdom UI (XSS risk). Escape h and cell with html.escape(str(...), quote=True) (or an equivalent escaping utility already used in the project) before inserting into the <th>/<td> markup.

Copilot uses AI. Check for mistakes.
Comment on lines +969 to +974
assert isinstance(headers, list), "headers should be a list"
assert isinstance(data, list), "data should be a list of lists"
for row in data:
assert isinstance(row, list), "each row in data should be a list"
assert len(row) == len(headers), \
"each row length must match number of headers"
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using assert for runtime input validation is brittle because asserts can be disabled with Python optimizations (-O), which would remove these checks in production. Prefer raising TypeError/ValueError with the same messages (or more specific ones) so validation is enforced consistently.

Suggested change
assert isinstance(headers, list), "headers should be a list"
assert isinstance(data, list), "data should be a list of lists"
for row in data:
assert isinstance(row, list), "each row in data should be a list"
assert len(row) == len(headers), \
"each row length must match number of headers"
if not isinstance(headers, list):
raise TypeError("headers should be a list")
if not isinstance(data, list):
raise TypeError("data should be a list of lists")
for row in data:
if not isinstance(row, list):
raise TypeError("each row in data should be a list")
if len(row) != len(headers):
raise ValueError("each row length must match number of headers")

Copilot uses AI. Check for mistakes.
Comment on lines +983 to +994
# Build rows HTML
rows_html = ''
for i, row in enumerate(data):
bg = '#fafafa' if i % 2 == 0 else '#ffffff'
cells = ''.join(
'<td style="padding:6px 12px; '
'border-bottom:1px solid #ddd;">%s</td>' % str(cell)
for cell in row
)
rows_html += (
'<tr style="background:%s;">%s</tr>' % (bg, cells)
)
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Building rows_html via repeated string concatenation in a loop is O(n²) in total copied characters for large tables. Use a list accumulator (append each <tr>...</tr>) and ''.join(rows) at the end to keep it O(n) and reduce allocations.

Copilot uses AI. Check for mistakes.
Comment on lines +997 to +1003
table_html = (
'<table style="border-collapse:collapse; '
'width:100%%; font-family:monospace;">'
'<thead><tr>%s</tr></thead>'
'<tbody>%s</tbody>'
'</table>'
) % (header_html, rows_html)
Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The PR description mentions 'hover effects', but the generated markup only sets static inline styles (no :hover styling and no JS). Either update the description to match the current implementation or add a hover style (e.g., via embedded <style> and a class-based selector) so the feature matches the stated behavior.

Copilot uses AI. Check for mistakes.
Comment on lines +951 to +953

)

Copy link

Copilot AI Mar 23, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There appears to be an extra blank line/trailing whitespace introduced around the end of the preceding call. Please remove trailing whitespace and keep formatting consistent to avoid lint/format churn in future diffs.

Suggested change
)
)

Copilot uses AI. Check for mistakes.
@nitininhouse
Copy link
Author

Hello @mariobehling @marcoag @norbusan
Could you please review it

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add table() method for displaying formatted HTML tables

2 participants