Skip to content

fix(ui): chart hover under zoom, Format autocomplete, Library/History search#33

Merged
BorisTyshkevich merged 2 commits into
mainfrom
feat/ui-fixes
Jun 24, 2026
Merged

fix(ui): chart hover under zoom, Format autocomplete, Library/History search#33
BorisTyshkevich merged 2 commits into
mainfrom
feat/ui-fixes

Conversation

@BorisTyshkevich

Copy link
Copy Markdown
Collaborator

Three UI fixes found in manual testing on the otel demo. All verified live (otel) and unit-tested; per-file coverage gate holds.

1. Chart hover position under page zoom (bar / column / pie)

The app ships html { zoom: 1.2 }. Chart.js resolves pointer hits from the event's offsetX/offsetY, which the browser reports in zoomed pixels, while the chart draws in an unzoomed coordinate system — so every hover landed ~1.2× too far along the axis: long bars read past their end, short bars near the origin never registered, and the tooltip drifted right. Affected all hit-tested types (bar, column, pie).

Fix: a pure unzoomChartEvent(e, scale) (core/chart-data.js) divides the resolved coords by the live zoom scale, wired via installChartZoomFix into the controller's single _eventHandler entry point (late-bound property, so the override runs before inChartArea / hit-testing). zoomScale(canvas) reads the factor each event → no-op (scale 1) when unzoomed.

Verified: hovering long and short bars now anchors the tooltip on the bar under the cursor (e.g. xterm-256color → 52,798).

2. Format opened an irrelevant autocomplete dropdown

After Format, the caret sat at the end of the last token (… LIMIT 10), so the input event from the in-place replace re-opened the completion dropdown on that word (exp10, log10, …).

Fix: withStatementBreak (core/format.js) appends a single newline to the formatted SQL only when it doesn't already end in whitespace or ;, so the caret clears the token. (Per @BorisTyshkevich's diagnosis.)

3. Search / filter for Library & History

Per the design spec, added a search box to the side panel that filters the active list — name/description/SQL for Library, SQL for History — with a search icon, clear (×) button, Escape-to-clear, per-tab placeholder, and a “no matches” state. Cleared when switching tabs. Pure filterSaved / filterHistory (state.js); the input re-renders only the list so typing keeps focus.


Tests: chart-data / format / state / results / saved-history / app specs updated; npm test green (734 passing). Built and deployed to otel for manual verification.

🤖 Generated with Claude Code

BorisTyshkevich and others added 2 commits June 24, 2026 13:55
… search

Three UI fixes surfaced in manual testing:

- chart hover (bar/column/pie): under the shipped `html{zoom:1.2}`, Chart.js
  maps pointer events from zoomed-px offsetX while drawing in unzoomed coords,
  so every hover landed ~1.2x too far along the axis — long bars read past
  their end, short bars never registered, the tooltip drifted right. Add a
  pure `unzoomChartEvent(e, scale)` (core/chart-data.js) and wire it via
  `installChartZoomFix` into the controller's single `_eventHandler` entry
  point (late-bound) so coords are corrected before hit-testing / in-area.

- Format: after Format the caret sat at the end of the last token, so the
  input event from the replace re-opened autocomplete on it. `withStatementBreak`
  (core/format.js) appends a newline only when the SQL doesn't already end in
  whitespace or ';', clearing the caret off the word.

- Library/History search: add a search box to the side panel (per design spec)
  filtering the active list — name/description/sql for Library, sql for History
  — with a clear (x) button, Escape-to-clear, per-tab placeholder and a
  no-matches state; cleared on tab switch. Pure `filterSaved`/`filterHistory`
  in state.js; the input re-renders only the list so typing keeps focus.

Pure logic is 100%-covered; render/state files hold the per-file gate.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QGBS74oUsXarGkCRQKEFLu
A ready-made saved-queries Library that demonstrates every chart type/feature
against the public `ontime` flight dataset, plus a how-to manual.

- examples/ontime-charts.json — 10 queries (Bar/Column/Line/Area/Pie, grouped
  Series, multi-measure, and a row-cap example), each carrying a chart config
  that opens by default. Load via File → Replace.
- examples/build-ontime-charts.mjs — regenerates the JSON; derives each entry's
  schema key live (clickhouse-client --connection antalya DESCRIBE) so the saved
  chart config restores instead of falling back to autoChart.
- docs/ONTIME-CHART-DEMO.md — load steps, a query↔chart↔feature table, and
  per-query deep links to https://antalya.demo.altinity.cloud/sql.
- README: "Demo & examples" section linking the live demo + manual.

Verified live on antalya /sql (the feat/ui-fixes build): all 10 open in the
intended chart type, the cap note shows "first 500 of 1.5K rows", and hover
tracks the bar under the cursor.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QGBS74oUsXarGkCRQKEFLu
@BorisTyshkevich BorisTyshkevich merged commit fdd7c73 into main Jun 24, 2026
2 checks passed
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.

1 participant