Skip to content

Commit 5e33602

Browse files
committed
[claude] connect line across missing-data commits
Flip `spanGaps` back to `true` in chart-init.js so the line connects to the next available data point across nulls. The point markers themselves are still only drawn at non-null indices, so the missing commit is visible as a missing marker — but the line bridges the gap. The server-side fix (commits with no data still appear in `commits[]`) stays unchanged: hovering on a missing-data commit still shows it as a real commit on the x-axis. The change is purely visual — no broken segments where the line only has occasional gaps. Bumped `STATIC_ASSET_VERSION` to `bench-v3-ui-20` and updated snapshots. Signed-off-by: Claude <noreply@anthropic.com>
1 parent 112b1bf commit 5e33602

5 files changed

Lines changed: 21 additions & 16 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-19";
24+
pub(crate) const STATIC_ASSET_VERSION: &str = "bench-v3-ui-20";
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: 17 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -582,11 +582,13 @@
582582
var rawValues = Array.isArray(raw[name]) ? raw[name] : [];
583583
// `data` starts null-padded; `rebuildVisibleAndUpdate` fills the
584584
// current visible window with raw or LTTB-kept values. Chart.js's
585-
// `spanGaps: false` makes the line break visibly at every null —
586-
// commits where this series has no measurement (a benchmark crashed,
587-
// a series only runs nightly, etc.) appear as a real gap rather than
588-
// being silently bridged. The previous `spanGaps: true` made
589-
// partial-coverage runs look like continuous lines.
585+
// `spanGaps: true` connects the line across nulls so a series with
586+
// partial coverage (a benchmark crashed at one commit, a series
587+
// only runs nightly, etc.) still draws as a continuous trend
588+
// through the surrounding measurements. The point markers
589+
// themselves are only drawn at non-null indices, so the missing
590+
// commits are visible as a "no marker" beat in the line — the line
591+
// itself bridges to the next available data point.
590592
var data = new Array(n);
591593
for (var j = 0; j < n; j++) data[j] = null;
592594
return {
@@ -596,7 +598,7 @@
596598
borderColor: colorFor(i),
597599
backgroundColor: colorFor(i) + "20",
598600
borderWidth: 1.5,
599-
spanGaps: false,
601+
spanGaps: true,
600602
tension: 0,
601603
pointRadius: 2,
602604
pointHoverRadius: 5,
@@ -618,8 +620,8 @@
618620
// `MAX_VISIBLE_POINTS` and LTTB-downsamples to exactly that number when
619621
// above. The result is written into `dataset.data` with nulls outside
620622
// the kept set so Chart.js renders just the kept points; with
621-
// `spanGaps: false`, nulls show up as visible gaps in the line so
622-
// missing measurements are obvious rather than silently bridged.
623+
// `spanGaps: true`, the line connects across the nulls to the next
624+
// non-null point so a sparse series still reads as a continuous trend.
623625
//
624626
// Mutates `dataset.data` in place to avoid GC churn on every pan frame.
625627
// Updates the per-card downsample badge as a side effect.
@@ -688,10 +690,13 @@
688690
}
689691

690692
// Plant the shared kept set into every dataset.data. Series that have
691-
// no value at a kept index simply remain null there. With
692-
// `spanGaps: false`, those nulls render as visible gaps — partial-
693-
// coverage commits (a benchmark crashed, a series only runs nightly)
694-
// show up as a break in the line rather than being silently bridged.
693+
// no value at a kept index simply remain null there; with
694+
// `spanGaps: true`, the line connects to the next non-null point so
695+
// a series with partial coverage (a benchmark crashed, a series only
696+
// runs nightly) still draws as a continuous trend through the
697+
// surrounding measurements. Markers are only drawn at non-null
698+
// indices, so the gap is still visible as a missing point — just not
699+
// as a broken line.
695700
for (var dj = 0; dj < datasets.length; dj++) {
696701
var ds = datasets[dj];
697702
var dsRaw = ds.rawData;

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-19"></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-19" alt="Vortex"><img class="site-logo logo-dark" src="/Vortex_White_NoBG.png?v=bench-v3-ui-19" 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-19" defer></script><script src="/static/chartjs-plugin-zoom.umd.min.js?v=bench-v3-ui-19" defer></script><script src="/static/chart-init.js?v=bench-v3-ui-19" 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-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>

0 commit comments

Comments
 (0)