Skip to content

Commit 01ac8b8

Browse files
committed
[claude] extend the rendered line past the visible window edges
When the user zoomed in tight, the line broke at the window's left and right edges — Chart.js was only seeing non-null `data[i]` for indices inside `[scales.x.min, scales.x.max]`, so the leftmost/rightmost in-range point had no off-screen neighbour to draw a line *to*. Visually this looked like "a few floating dots" until the user zoomed back out. Fix: in `rebuildVisibleAndUpdate`, after planting the LTTB-kept points, also plant the nearest non-null value just outside `[min, max]` on each side, per series. Chart.js draws the line from those off-screen points into the visible region; canvas clipping handles the rest. Cost is at most two extra data points per series, only on the rebuild path that already runs once per pan/zoom frame. Bumped `STATIC_ASSET_VERSION` to `bench-v3-ui-21`. Signed-off-by: Claude <noreply@anthropic.com>
1 parent 5e33602 commit 01ac8b8

5 files changed

Lines changed: 30 additions & 4 deletions

File tree

benchmarks-website/server/src/html/static_assets.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ const VORTEX_WHITE_PNG: &[u8] = include_bytes!("../../../public/Vortex_White_NoB
2121

2222
/// Cache-busting suffix appended to every static asset URL. Bump on a UI
2323
/// release so cached browsers see the new bytes.
24-
pub(crate) const STATIC_ASSET_VERSION: &str = "bench-v3-ui-20";
24+
pub(crate) const STATIC_ASSET_VERSION: &str = "bench-v3-ui-21";
2525

2626
/// Append the cache-bust query param to a static asset URL.
2727
pub(crate) fn versioned_asset(path: &str) -> String {

benchmarks-website/server/static/chart-init.js

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -697,6 +697,16 @@
697697
// surrounding measurements. Markers are only drawn at non-null
698698
// indices, so the gap is still visible as a missing point — just not
699699
// as a broken line.
700+
//
701+
// Edge-extension: for each series, also fill in the nearest non-null
702+
// value just *outside* `[min, max]` on each side. Chart.js's scale
703+
// `min`/`max` clip the canvas but still draw lines whose endpoints
704+
// lie outside that range; without these neighbours the line would
705+
// start/end at the nearest in-range point and visually break at the
706+
// window's edge — exactly the "zoom in and see only a few floating
707+
// dots" symptom the user reported. With them, the line continues
708+
// out of the visible region to the next real measurement and the
709+
// off-screen segment is naturally clipped.
700710
for (var dj = 0; dj < datasets.length; dj++) {
701711
var ds = datasets[dj];
702712
var dsRaw = ds.rawData;
@@ -714,6 +724,22 @@
714724
data[idx] = val;
715725
}
716726
}
727+
// Nearest non-null neighbour to the left of the visible window.
728+
for (var le = min - 1; le >= 0; le--) {
729+
var lv = dsRaw[le];
730+
if (lv !== null && lv !== undefined && !Number.isNaN(lv)) {
731+
data[le] = lv;
732+
break;
733+
}
734+
}
735+
// Nearest non-null neighbour to the right of the visible window.
736+
for (var re = max + 1; re < n; re++) {
737+
var rv = dsRaw[re];
738+
if (rv !== null && rv !== undefined && !Number.isNaN(rv)) {
739+
data[re] = rv;
740+
break;
741+
}
742+
}
717743
}
718744

719745
var visibleCommits = max - min + 1;

benchmarks-website/server/tests/snapshots/chart_page_query.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,4 @@
22
source: benchmarks-website/server/tests/web_ui.rs
33
expression: body
44
---
5-
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>tpch sf=1 Q1 [nvme] — bench.vortex.dev</title><script>(function(){try{var t=localStorage.getItem("bench-theme");if(t==="light"||t==="dark"){document.documentElement.dataset.theme=t;}}catch(e){}})();</script><link rel="stylesheet" href="/static/style.css?v=bench-v3-ui-20"></head><body><script id="bench-filter-state" type="application/json">{"engines":[],"formats":[]}</script><header class="sticky-header"><div class="header-content"><div class="header-left"><a class="logo-link" href="/" aria-label="bench.vortex.dev home"><img class="site-logo logo-light" src="/Vortex_Black_NoBG.png?v=bench-v3-ui-20" alt="Vortex"><img class="site-logo logo-dark" src="/Vortex_White_NoBG.png?v=bench-v3-ui-20" alt="Vortex"></a><h1 class="site-title">Vortex Benchmarks</h1></div><div class="header-center"><div class="nav-controls" aria-label="Benchmark group controls"><button class="control-btn" type="button" data-action="expand-all"><svg class="btn-icon" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m7 6 5 5 5-5"></path><path d="m7 13 5 5 5-5"></path></svg><span>Expand All</span></button><button class="control-btn" type="button" data-action="collapse-all"><svg class="btn-icon" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m17 18-5-5-5 5"></path><path d="m17 11-5-5-5 5"></path></svg><span>Collapse All</span></button><div class="filter-dropdown" data-role="global-filter-bar"><button class="control-btn filter-trigger" type="button" data-role="filter-trigger" aria-haspopup="true" aria-expanded="false"><svg class="btn-icon" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon></svg><span>Filters</span></button><div class="filter-panel" data-role="filter-panel" hidden><div class="global-filter-row"><span class="global-filter-label">Engine</span><button class="filter-chip filter-chip--all" type="button" data-filter="engine" data-value="*" aria-pressed="false">all</button><button class="filter-chip filter-chip--active" type="button" data-filter="engine" data-value="datafusion" aria-pressed="true">datafusion</button><button class="filter-chip filter-chip--active" type="button" data-filter="engine" data-value="duckdb" aria-pressed="true">duckdb</button></div><div class="global-filter-row"><span class="global-filter-label">Format</span><button class="filter-chip filter-chip--all" type="button" data-filter="format" data-value="*" aria-pressed="false">all</button><button class="filter-chip filter-chip--active" type="button" data-filter="format" data-value="parquet" aria-pressed="true">parquet</button><button class="filter-chip filter-chip--active" type="button" data-filter="format" data-value="vortex-file-compressed" aria-pressed="true">vortex-file-compressed</button></div></div></div></div></div><div class="header-right"><a class="repo-link" href="https://github.com/vortex-data/vortex" rel="noopener noreferrer" target="_blank"><svg class="github-logo" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg><span>GitHub</span></a><button class="control-btn theme-toggle" type="button" data-role="theme-toggle" data-next-theme="light" aria-label="Toggle color theme"><svg class="btn-icon theme-icon theme-icon-light" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2"></path><path d="M12 20v2"></path><path d="m4.93 4.93 1.41 1.41"></path><path d="m17.66 17.66 1.41 1.41"></path><path d="M2 12h2"></path><path d="M20 12h2"></path><path d="m6.34 17.66-1.41 1.41"></path><path d="m19.07 4.93-1.41 1.41"></path></svg><svg class="btn-icon theme-icon theme-icon-dark" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20.99 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 20.99 12.79z"></path></svg><span class="theme-toggle-label">Light</span></button></div></div></header><main><p class="chart-meta">unit: <code>ns</code> · 2 series · 3 commits<span class="chart-badge chart-badge--downsampled" data-role="downsample-badge" hidden></span></p><section class="chart-card" data-chart-index="0" data-chart-slug="qm.eyJrIjoiUXVlcnlNZWFzdXJlbWVudCIsImRhdGFzZXQiOiJ0cGNoIiwiZGF0YXNldF92YXJpYW50IjpudWxsLCJzY2FsZV9mYWN0b3IiOiIxIiwic3RvcmFnZSI6Im52bWUiLCJxdWVyeV9pZHgiOjF9"><div class="toolbar toolbar--card" aria-label="Chart controls"><div class="toolbar-group" role="group" aria-label="Visible commits"><span class="toolbar-label">Show</span><input class="toolbar-slider" id="scope-slider-0" type="range" min="5" max="100" step="1" value="100" data-role="scope-slider" aria-label="Custom commit window"></div><div class="toolbar-group" role="group" aria-label="Y-axis scale"><span class="toolbar-label">Y</span><button class="toolbar-btn toolbar-btn--active" type="button" data-y="linear">linear</button><button class="toolbar-btn" type="button" data-y="log">log</button></div></div><div class="chart-tooltip-host"></div><div class="chart-wrap"><canvas data-chart-index="0"></canvas></div><div class="chart-range-strip" data-chart-index="0" data-role="range-strip" aria-label="Visible commit range" role="slider"><div class="chart-range-strip-track"><div class="chart-range-strip-window" data-role="range-window"><span class="chart-range-strip-handle chart-range-strip-handle--left" data-role="range-handle-left" aria-hidden="true"></span><span class="chart-range-strip-handle chart-range-strip-handle--right" data-role="range-handle-right" aria-hidden="true"></span></div></div></div><script id="chart-data-0" type="application/json">{"display_name":"tpch sf=1 Q1 [nvme]","unit":"ns","commits":[{"sha":"1111111111111111111111111111111111111111","timestamp":"2026-04-23 12:00:00+00","message":"first commit","url":"https://github.com/vortex-data/vortex/commit/1111111111111111111111111111111111111111"},{"sha":"2222222222222222222222222222222222222222","timestamp":"2026-04-24 12:00:00+00","message":"second commit","url":"https://github.com/vortex-data/vortex/commit/2222222222222222222222222222222222222222"},{"sha":"3333333333333333333333333333333333333333","timestamp":"2026-04-25 12:00:00+00","message":"third commit","url":"https://github.com/vortex-data/vortex/commit/3333333333333333333333333333333333333333"}],"series":{"datafusion:vortex-file-compressed":[1000000.0,1050000.0,1100000.0],"duckdb:parquet":[800000.0,850000.0,900000.0]},"series_meta":{"datafusion:vortex-file-compressed":{"engine":"datafusion","format":"vortex-file-compressed"},"duckdb:parquet":{"engine":"duckdb","format":"parquet"}}}</script></section><noscript><p class="no-script">JavaScript is required to render the chart.</p></noscript></main><script src="/static/chart.umd.js?v=bench-v3-ui-20" defer></script><script src="/static/chartjs-plugin-zoom.umd.min.js?v=bench-v3-ui-20" defer></script><script src="/static/chart-init.js?v=bench-v3-ui-20" defer></script></body></html>
5+
<!DOCTYPE html><html lang="en"><head><meta charset="utf-8"><meta name="viewport" content="width=device-width, initial-scale=1"><title>tpch sf=1 Q1 [nvme] — bench.vortex.dev</title><script>(function(){try{var t=localStorage.getItem("bench-theme");if(t==="light"||t==="dark"){document.documentElement.dataset.theme=t;}}catch(e){}})();</script><link rel="stylesheet" href="/static/style.css?v=bench-v3-ui-21"></head><body><script id="bench-filter-state" type="application/json">{"engines":[],"formats":[]}</script><header class="sticky-header"><div class="header-content"><div class="header-left"><a class="logo-link" href="/" aria-label="bench.vortex.dev home"><img class="site-logo logo-light" src="/Vortex_Black_NoBG.png?v=bench-v3-ui-21" alt="Vortex"><img class="site-logo logo-dark" src="/Vortex_White_NoBG.png?v=bench-v3-ui-21" alt="Vortex"></a><h1 class="site-title">Vortex Benchmarks</h1></div><div class="header-center"><div class="nav-controls" aria-label="Benchmark group controls"><button class="control-btn" type="button" data-action="expand-all"><svg class="btn-icon" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m7 6 5 5 5-5"></path><path d="m7 13 5 5 5-5"></path></svg><span>Expand All</span></button><button class="control-btn" type="button" data-action="collapse-all"><svg class="btn-icon" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="m17 18-5-5-5 5"></path><path d="m17 11-5-5-5 5"></path></svg><span>Collapse All</span></button><div class="filter-dropdown" data-role="global-filter-bar"><button class="control-btn filter-trigger" type="button" data-role="filter-trigger" aria-haspopup="true" aria-expanded="false"><svg class="btn-icon" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><polygon points="22 3 2 3 10 12.46 10 19 14 21 14 12.46 22 3"></polygon></svg><span>Filters</span></button><div class="filter-panel" data-role="filter-panel" hidden><div class="global-filter-row"><span class="global-filter-label">Engine</span><button class="filter-chip filter-chip--all" type="button" data-filter="engine" data-value="*" aria-pressed="false">all</button><button class="filter-chip filter-chip--active" type="button" data-filter="engine" data-value="datafusion" aria-pressed="true">datafusion</button><button class="filter-chip filter-chip--active" type="button" data-filter="engine" data-value="duckdb" aria-pressed="true">duckdb</button></div><div class="global-filter-row"><span class="global-filter-label">Format</span><button class="filter-chip filter-chip--all" type="button" data-filter="format" data-value="*" aria-pressed="false">all</button><button class="filter-chip filter-chip--active" type="button" data-filter="format" data-value="parquet" aria-pressed="true">parquet</button><button class="filter-chip filter-chip--active" type="button" data-filter="format" data-value="vortex-file-compressed" aria-pressed="true">vortex-file-compressed</button></div></div></div></div></div><div class="header-right"><a class="repo-link" href="https://github.com/vortex-data/vortex" rel="noopener noreferrer" target="_blank"><svg class="github-logo" viewBox="0 0 16 16" width="16" height="16" fill="currentColor" aria-hidden="true"><path d="M8 0C3.58 0 0 3.58 0 8c0 3.54 2.29 6.53 5.47 7.59.4.07.55-.17.55-.38 0-.19-.01-.82-.01-1.49-2.01.37-2.53-.49-2.69-.94-.09-.23-.48-.94-.82-1.13-.28-.15-.68-.52-.01-.53.63-.01 1.08.58 1.23.82.72 1.21 1.87.87 2.33.66.07-.52.28-.87.51-1.07-1.78-.2-3.64-.89-3.64-3.95 0-.87.31-1.59.82-2.15-.08-.2-.36-1.02.08-2.12 0 0 .67-.21 2.2.82.64-.18 1.32-.27 2-.27.68 0 1.36.09 2 .27 1.53-1.04 2.2-.82 2.2-.82.44 1.1.16 1.92.08 2.12.51.56.82 1.27.82 2.15 0 3.07-1.87 3.75-3.65 3.95.29.25.54.73.54 1.48 0 1.07-.01 1.93-.01 2.2 0 .21.15.46.55.38A8.013 8.013 0 0016 8c0-4.42-3.58-8-8-8z"></path></svg><span>GitHub</span></a><button class="control-btn theme-toggle" type="button" data-role="theme-toggle" data-next-theme="light" aria-label="Toggle color theme"><svg class="btn-icon theme-icon theme-icon-light" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><circle cx="12" cy="12" r="4"></circle><path d="M12 2v2"></path><path d="M12 20v2"></path><path d="m4.93 4.93 1.41 1.41"></path><path d="m17.66 17.66 1.41 1.41"></path><path d="M2 12h2"></path><path d="M20 12h2"></path><path d="m6.34 17.66-1.41 1.41"></path><path d="m19.07 4.93-1.41 1.41"></path></svg><svg class="btn-icon theme-icon theme-icon-dark" viewBox="0 0 24 24" width="16" height="16" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round" aria-hidden="true"><path d="M20.99 12.79A9 9 0 1 1 11.21 3 7 7 0 0 0 20.99 12.79z"></path></svg><span class="theme-toggle-label">Light</span></button></div></div></header><main><p class="chart-meta">unit: <code>ns</code> · 2 series · 3 commits<span class="chart-badge chart-badge--downsampled" data-role="downsample-badge" hidden></span></p><section class="chart-card" data-chart-index="0" data-chart-slug="qm.eyJrIjoiUXVlcnlNZWFzdXJlbWVudCIsImRhdGFzZXQiOiJ0cGNoIiwiZGF0YXNldF92YXJpYW50IjpudWxsLCJzY2FsZV9mYWN0b3IiOiIxIiwic3RvcmFnZSI6Im52bWUiLCJxdWVyeV9pZHgiOjF9"><div class="toolbar toolbar--card" aria-label="Chart controls"><div class="toolbar-group" role="group" aria-label="Visible commits"><span class="toolbar-label">Show</span><input class="toolbar-slider" id="scope-slider-0" type="range" min="5" max="100" step="1" value="100" data-role="scope-slider" aria-label="Custom commit window"></div><div class="toolbar-group" role="group" aria-label="Y-axis scale"><span class="toolbar-label">Y</span><button class="toolbar-btn toolbar-btn--active" type="button" data-y="linear">linear</button><button class="toolbar-btn" type="button" data-y="log">log</button></div></div><div class="chart-tooltip-host"></div><div class="chart-wrap"><canvas data-chart-index="0"></canvas></div><div class="chart-range-strip" data-chart-index="0" data-role="range-strip" aria-label="Visible commit range" role="slider"><div class="chart-range-strip-track"><div class="chart-range-strip-window" data-role="range-window"><span class="chart-range-strip-handle chart-range-strip-handle--left" data-role="range-handle-left" aria-hidden="true"></span><span class="chart-range-strip-handle chart-range-strip-handle--right" data-role="range-handle-right" aria-hidden="true"></span></div></div></div><script id="chart-data-0" type="application/json">{"display_name":"tpch sf=1 Q1 [nvme]","unit":"ns","commits":[{"sha":"1111111111111111111111111111111111111111","timestamp":"2026-04-23 12:00:00+00","message":"first commit","url":"https://github.com/vortex-data/vortex/commit/1111111111111111111111111111111111111111"},{"sha":"2222222222222222222222222222222222222222","timestamp":"2026-04-24 12:00:00+00","message":"second commit","url":"https://github.com/vortex-data/vortex/commit/2222222222222222222222222222222222222222"},{"sha":"3333333333333333333333333333333333333333","timestamp":"2026-04-25 12:00:00+00","message":"third commit","url":"https://github.com/vortex-data/vortex/commit/3333333333333333333333333333333333333333"}],"series":{"datafusion:vortex-file-compressed":[1000000.0,1050000.0,1100000.0],"duckdb:parquet":[800000.0,850000.0,900000.0]},"series_meta":{"datafusion:vortex-file-compressed":{"engine":"datafusion","format":"vortex-file-compressed"},"duckdb:parquet":{"engine":"duckdb","format":"parquet"}}}</script></section><noscript><p class="no-script">JavaScript is required to render the chart.</p></noscript></main><script src="/static/chart.umd.js?v=bench-v3-ui-21" defer></script><script src="/static/chartjs-plugin-zoom.umd.min.js?v=bench-v3-ui-21" defer></script><script src="/static/chart-init.js?v=bench-v3-ui-21" defer></script></body></html>

0 commit comments

Comments
 (0)