Skip to content

fix: inherit explore default timezone in chat charts without time_zone - #9839

Open
eminemead wants to merge 1 commit into
rilldata:mainfrom
eminemead:xiaofei.yin/fix-chart-timezone-inherit
Open

fix: inherit explore default timezone in chat charts without time_zone#9839
eminemead wants to merge 1 commit into
rilldata:mainfrom
eminemead:xiaofei.yin/fix-chart-timezone-inherit

Conversation

@eminemead

Copy link
Copy Markdown
  • Chat charts whose spec omits time_zone were always binned in UTC, so day grains did not match the explore default timezone.
  • ChartBlock now resolves timezone the same way dashboards do: explicit spec time_zone, else the explore defaultPreset.timezone / first timeZones entry, else UTC.
  • getDefaultTimeZone honors defaultPreset.timezone first. An explicit spec zone stays authoritative.

Checklist:

  • Covered by tests
  • Ran it and it works as intended
  • Reviewed the diff before requesting a review
  • Checked for unhandled edge cases
  • Linked the issues it closes
  • Checked if the docs need to be updated. If so, create a separate Linear DOCS issue
  • Intend to cherry-pick into the release branch
  • I'm proud of this work!

Developed in collaboration with Claude Code

Explain charts omit time_zone and were binned in UTC. Resolve the same explore default as dashboards, keeping an explicit spec zone authoritative and falling back to UTC when no explore is available.
@nishantmonu51 nishantmonu51 added Type:Bug Something isn't working Area:Time Size:M Medium change: 100-499 lines labels Sep 1, 2026
@nishantmonu51

Copy link
Copy Markdown
Collaborator

1. The getDefaultTimeZone change breaks explore URL state — 20 existing tests fail.

On this branch, npx vitest run src/features/dashboards/url-state fails 20 tests in url-state-variations.spec.ts and convertURLSearchParamsToExploreState.spec.ts, all with the same shape:

Expected: "tr=P7D&tz=Asia%2FKathmandu&compare_tr=rill-PP&..."
Received: "tr=P7D&compare_tr=rill-PP&..."

These pass on main. getRillDefaultExploreState feeds getRillDefaultExploreUrlParams, which getCleanedUrlParamsForGoto uses to strip params that match the defaults. Folding defaultPreset.timezone into getDefaultTimeZone means tz is now dropped from the URL of every dashboard that sets defaults: timezone:, so shared and bookmarked links no longer carry the timezone explicitly.

The layering here is deliberate: DashboardStateDataLoader keeps rillDefaultExploreState and exploreStateFromYAMLConfig as separate layers, and the YAML layer already applies the preset timezone (get-explore-state-from-yaml-config.ts:126). getDefaultExplorePreset also spreads ...explore.defaultPreset after timezone: getDefaultTimeZone(explore), so the preset already wins there. In other words, the change to getDefaultTimeZone is not needed for dashboards — it only shifts the pre-YAML baseline. Resolving the preset inside resolveChartTimeZone instead keeps the fix scoped to the chat chart:

export function resolveChartTimeZone(explicitTimeZone, explore) {
  if (explicitTimeZone) return explicitTimeZone;
  if (!explore) return getUTCIANA();
  return getDefaultTimeZone({
    ...explore,
    timeZones: explore.defaultPreset?.timezone
      ? [explore.defaultPreset.timezone, ...(explore.timeZones ?? [])]
      : explore.timeZones,
  });
}

(or simply read defaultPreset?.timezone first and pass it through the same Local/IANA normalization).

2. The explore that supplies the timezone is chosen arbitrarily, and the selection is duplicated.

selectBestDashboard with the default first_available criteria returns validDashboards[0] — whichever explore ListResources happens to return first. When a metrics view backs several explores with different timeZones, the chart's binning becomes dependent on resource ordering rather than on any user-visible dashboard. ChartContainer already runs the same query and the same selection through useExploreAvailability for the explore link, so the component now performs that selection twice with no guarantee, other than identical inputs, that the timezone comes from the dashboard the link points at. Extending useExploreAvailability to also return the selected validSpec (or adding a shared selector both call) would make the coupling explicit and remove the duplicate.

3. The chart is blank while the explores query is in flight.

{#if timezoneReady} hides ChartContainer entirely, with nothing in its place, so the chart area collapses and then pops back in once ListResources resolves — a visible layout shift in the chat transcript, and one that happens for every chart whose spec omits time_zone. Rendering the container with its existing loading state, or reserving the height, avoids the jump while still preventing the UTC-then-refetch problem the comment describes.

4. Minor: the UTC branch in resolveChartTimeZone is redundant.

getDefaultTimeZone({}) already returns DEFAULT_TIMEZONES[0], which the new spec asserts is "UTC", so if (!explore) return getUTCIANA() can be getDefaultTimeZone(explore ?? {}). Similarly, resolveChartTimeZone already treats "" as absent (there is a test for it), so the typeof … === "string" && … narrowing in ChartBlock.svelte only exists to keep timezoneReady honest — passing chartSpec.time_range?.time_zone straight through and computing readiness from the same value would read more directly.

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

Labels

Area:Time Size:M Medium change: 100-499 lines Type:Bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants