Skip to content

DataTables headers lose synchronization and truncate when plotting many annotation columns #126

@IgnatiusPang

Description

@IgnatiusPang

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions