Description
When providing a large number of annotation columns (e.g., 10+ metadata or GO term columns) via the anno argument in glimmaXY or glimmaVolcano, the interactive DataTables table at the bottom of the HTML output breaks its layout.
Specifically, the headers detach and fail to scroll horizontally in sync with the table body, and any columns pushed far to the right become inaccessible or visually misaligned.
Root Cause Analysis
Upon inspecting the generated HTML and the underlying glimmaXY.js source code, the DataTable is initialized dynamically but lacks the explicit scrollX: true configuration option.
Because scrollX is not enabled, DataTables forces the table rendering into the fixed width of the flexbox container. When it runs out of horizontal space, it only displays a limited number of column headers, causing the header (<thead>) and body (<tbody>) widths to fall completely out of sync and break the layout.
Ideally, the column header width should be the same length as the data column no matter how long the data field is. There should only be one horizontal scrolling bar that moves the column header and the column data together and in synchrony.
Reproducible Example
library(Glimma)
library(edgeR)
# Create mock expression data
y <- matrix(rnorm(1000*6), 1000, 6)
rownames(y) <- paste0("Gene", 1:1000)
# Create a wide annotation dataframe with 20 columns
wide_anno <- data.frame(
GeneID = rownames(y),
GeneName = paste0("Name", 1:1000),
Description = "Test protein description that is reasonably long"
)
# Add 17 more filler columns to force overflow
for(i in 1:17) {
wide_anno[[paste0("Extra_Annotation_", i)]] <- paste0("Metadata value ", i)
}
# Generate plot
glimmaXY(
x = rnorm(1000),
y = -log10(runif(1000)),
counts = y,
transform.counts = "none",
anno = wide_anno,
html = "test_wide_table.html"
)
Expected Behavior
The table should seamlessly scroll horizontally (overflow-x: auto), keeping the column headers perfectly anchored and aligned with their respective data cells, regardless of how many columns are provided in the anno dataframe.
Suggested Fix / Workaround
For Maintainers:
In htmlwidgets/glimmaXY.js, inject scrollX: true into the DataTables initialization object:
const datatable = $(datatableEl).DataTable({
data: data.xyTable,
columns: data.cols.map((el) => ({ "data": el, "title": el })),
rowId: "gene",
scrollX: true, // <-- Fix
// ...
Temporary User Workaround:
As a temporary fix, R users can forcefully inject CSS into the generated HTML <head> before serving it. This CSS utilizes display: contents to re-unify the split DataTables containers into a single logical table DOM, ensuring that column widths naturally synchronize without relying on Javascript listeners:
# After generating the plot:
html_lines <- readLines("volcano.html")
css_fix <- "<style> .dataTables_wrapper { overflow-x: auto !important; } .dataTables_scroll { display: table !important; width: auto !important; min-width: 100% !important; } .dataTables_scrollHead, .dataTables_scrollBody, .dataTables_scrollHeadInner, .dataTables_scrollHeadInner > table, .dataTables_scrollBody > table { display: contents !important; } .dataTables_scrollBody thead { display: none !important; } .dataTable th, .dataTable td { white-space: nowrap !important; } </style></head>"
writeLines(sub("</head>", css_fix, html_lines), "volcano.html")
Environment
- Glimma Version: 2.20.0 (or current)
- Browser: Tested on Chrome/Firefox/Safari
- OS: macOS / Windows
This issue report was written with the assistance of Antigravity (gemini 3 pro) and then manually reviewed to assure correctness and reliability.
Description
When providing a large number of annotation columns (e.g., 10+ metadata or GO term columns) via the
annoargument inglimmaXYorglimmaVolcano, the interactive DataTables table at the bottom of the HTML output breaks its layout.Specifically, the headers detach and fail to scroll horizontally in sync with the table body, and any columns pushed far to the right become inaccessible or visually misaligned.
Root Cause Analysis
Upon inspecting the generated HTML and the underlying
glimmaXY.jssource code, theDataTableis initialized dynamically but lacks the explicitscrollX: trueconfiguration option.Because
scrollXis not enabled, DataTables forces the table rendering into the fixed width of the flexbox container. When it runs out of horizontal space, it only displays a limited number of column headers, causing the header (<thead>) and body (<tbody>) widths to fall completely out of sync and break the layout.Ideally, the column header width should be the same length as the data column no matter how long the data field is. There should only be one horizontal scrolling bar that moves the column header and the column data together and in synchrony.
Reproducible Example
Expected Behavior
The table should seamlessly scroll horizontally (
overflow-x: auto), keeping the column headers perfectly anchored and aligned with their respective data cells, regardless of how many columns are provided in theannodataframe.Suggested Fix / Workaround
For Maintainers:
In
htmlwidgets/glimmaXY.js, injectscrollX: trueinto the DataTables initialization object:Temporary User Workaround:
As a temporary fix, R users can forcefully inject CSS into the generated HTML
<head>before serving it. This CSS utilizesdisplay: contentsto re-unify the split DataTables containers into a single logical table DOM, ensuring that column widths naturally synchronize without relying on Javascript listeners:Environment
This issue report was written with the assistance of Antigravity (gemini 3 pro) and then manually reviewed to assure correctness and reliability.