Skip to content

Fix date tooltip: show human-readable dates instead of ms timestamps#66

Open
yihui with Copilot wants to merge 3 commits into
mainfrom
copilot/support-date-class-in-time-series
Open

Fix date tooltip: show human-readable dates instead of ms timestamps#66
yihui with Copilot wants to merge 3 commits into
mainfrom
copilot/support-date-class-in-time-series

Conversation

Copilot AI commented Apr 22, 2026

Copy link
Copy Markdown
Contributor

When a Date/POSIXt column is mapped to x, the tooltip displayed raw millisecond epoch values (e.g. 1767484800000) instead of readable date strings — both in the tooltip title and in tooltip items for point marks.

Why not just send ISO strings?

The ms-timestamp conversion in annotate_df must stay. G2's inferDomainQ computes the scale domain via +d (JS numeric coercion), and +"2026-01-01" === NaN — so sending ISO strings collapses all points to a single position. This was the original fix in PR #21.

Fix

build_config now:

  1. Tooltip title: Auto-injects a JS tooltip title formatter on each child mark when the x channel is a Date/POSIXt column and the mark doesn't already have a custom tooltip.title:

    • Date(d) => new Date(d["col"]).toLocaleDateString()
    • POSIXt(d) => new Date(d["col"]).toLocaleString()
  2. Tooltip items for point marks: For marks that use tooltip2d (point, cell, heatmap, image, link, beeswarm), also injects a valueFormatter on the x channel item so the date appears formatted in the items list too, not just the title. User-set tooltip$items is respected.

  3. UTC time scale: Adds utc: true to the auto-detected time scale. This switches D3 to its UTC-based time scale so tick positions are at UTC midnight — matching our UTC-based ms timestamps. Without this, in non-UTC timezones D3's local-time ticks were offset from the marks.

The column name is escaped via xfun::tojson() before interpolation. User-set tooltip$title and tooltip = FALSE are both respected.

# Tooltip title: shows "1/5/2026" instead of "1767484800000"
data.frame(date = seq(as.Date('2026-01-01'), as.Date('2026-01-10'), length.out = 10),
           value = 1:10) |>
  g2(value ~ date)

# Tooltip items for point marks also show formatted dates
data.frame(date = Sys.Date() + 1:10, value = 1:10) |>
  g2(value ~ date) |> mark_line() |> mark_point()

Copilot AI linked an issue Apr 22, 2026 that may be closed by this pull request
@yihui
yihui marked this pull request as ready for review April 22, 2026 05:01
Copilot AI changed the title [WIP] Fix tooltips to display real dates in time series Fix date tooltip: show human-readable dates instead of ms timestamps Apr 22, 2026
Copilot AI requested a review from yihui April 22, 2026 05:03

@yihui yihui left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

another problem is, tooltips for points still show timestamps:

data.frame(date = Sys.Date() + 1:10, value = 1:10) |> 
    g2(value ~ date) |> mark_line() |> mark_point()

when you hover over a point, the tooltip shows both date and value, and date is presented as large integers

i also discovered a different pre-existing problem, not related to this PR but very serious: the x-axis tick marks are not aligned with marks in the plot when x axis is date or time---the marks are off to the left of their corresponding tick marks, e.g., the mark for Jan 2 is to the left of the Jan 2 tickmark; i tried a normal plot with numeric x axis, and the plot marks aligned perfectly with axis tick marks:

data.frame(date = 1:10, value = 1:10) |> 
    g2(value ~ date) |> mark_line() |> mark_point()

pls do browser testing and provide screenshots as proof for your fix following copilot instructions, also wait for CI

Comment thread R/render.R Outdated
col_js = xfun::tojson(x_col)
fmt_fn = if (inherits(chart$data[[x_col]], 'Date'))
xfun::js(paste0(
'(d) => new Date(d[', col_js, ']).toISOString().slice(0, 10)'))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

.slice(0, 10) is not robust

Suggested change
'(d) => new Date(d[', col_js, ']).toISOString().slice(0, 10)'))
'(d) => new Date(d[', col_js, ']).toLocaleDateString()'))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 504b34b — changed to toLocaleDateString() for Date columns.

Comment thread R/render.R Outdated
Comment on lines +207 to +208
'(d) => new Date(d[', col_js, ']).toISOString()',
'.replace("T", " ").slice(0, 19)'))

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

similarly:

Suggested change
'(d) => new Date(d[', col_js, ']).toISOString()',
'.replace("T", " ").slice(0, 19)'))
'(d) => new Date(d[', col_js, ']).toLocaleString()'))

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in 504b34b — changed to toLocaleString() for POSIXt columns.

Comment thread NEWS.md Outdated
Comment on lines +3 to +5
- Date/POSIXt columns used as the x axis now show human-readable dates in
tooltips (e.g., `2026-01-01`) instead of raw millisecond timestamps.

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

follow instructions! no news for v0.1! remember this forever!

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Removed in 504b34b. Sorry about that — won't happen again.

- Use toLocaleDateString()/toLocaleString() per code review suggestions
- Add utc: TRUE to auto-detected time scale to fix tick alignment in non-UTC timezones
- Inject x item valueFormatter for tooltip2d marks (point, cell, heatmap, etc.) so date items also show readable dates instead of ms timestamps
- Remove NEWS.md entry for v0.1 (no individual changes for initial release)
- Update tests to match new behavior

Agent-Logs-Url: https://github.com/yihui/gglite/sessions/bbb7c4f2-4ec5-44fd-861b-f53d6e8913c2

Co-authored-by: yihui <163582+yihui@users.noreply.github.com>

Copilot AI commented Apr 22, 2026

Copy link
Copy Markdown
Contributor Author

another problem is, tooltips for points still show timestamps:

Fixed in 504b34b. Three things addressed:

  1. Tooltip items for mark_point(): For marks that use G2's tooltip2d (point, cell, heatmap, etc.), the x channel now appears with a valueFormatter that calls toLocaleDateString(), so the date item shows 1/3/2026 instead of a raw ms number.

  2. x-axis alignment: Added utc: true to the auto-detected time scale. This switches D3 to its UTC-based time scale, so tick positions are at UTC midnight — matching our UTC-based ms timestamps. In non-UTC timezones, D3's default local-time scale was placing ticks at local midnight while marks were at UTC midnight, causing the visible offset.

  3. toLocaleDateString() / toLocaleString(): Applied both code review suggestions.

Screenshots showing the fixed mark_line() |> mark_point() tooltip (title 1/3/2026, items value: 3 and date: 1/3/2026, no ms anywhere) and correct mark/tick alignment:

Tooltip on point mark:
tooltip

Line chart with correct tick alignment:
alignment

Copilot AI requested a review from yihui April 22, 2026 13:40
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.

Support Date class in time series

2 participants