@benchkit/chart 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +640 -0
- package/dist/ComparisonSummaryTable.test.d.ts +2 -0
- package/dist/ComparisonSummaryTable.test.d.ts.map +1 -0
- package/dist/ComparisonSummaryTable.test.js +53 -0
- package/dist/ComparisonSummaryTable.test.js.map +1 -0
- package/dist/Dashboard.d.ts +25 -0
- package/dist/Dashboard.d.ts.map +1 -0
- package/dist/Dashboard.js +87 -0
- package/dist/Dashboard.js.map +1 -0
- package/dist/Dashboard.test.d.ts +2 -0
- package/dist/Dashboard.test.d.ts.map +1 -0
- package/dist/Dashboard.test.js +49 -0
- package/dist/Dashboard.test.js.map +1 -0
- package/dist/RunDashboard.d.ts +20 -0
- package/dist/RunDashboard.d.ts.map +1 -0
- package/dist/RunDashboard.js +174 -0
- package/dist/RunDashboard.js.map +1 -0
- package/dist/RunDashboard.test.d.ts +2 -0
- package/dist/RunDashboard.test.d.ts.map +1 -0
- package/dist/RunDashboard.test.js +58 -0
- package/dist/RunDashboard.test.js.map +1 -0
- package/dist/RunDetail.d.ts +26 -0
- package/dist/RunDetail.d.ts.map +1 -0
- package/dist/RunDetail.js +100 -0
- package/dist/RunDetail.js.map +1 -0
- package/dist/RunDetail.test.d.ts +2 -0
- package/dist/RunDetail.test.d.ts.map +1 -0
- package/dist/RunDetail.test.js +168 -0
- package/dist/RunDetail.test.js.map +1 -0
- package/dist/RunSelector.test.d.ts +2 -0
- package/dist/RunSelector.test.d.ts.map +1 -0
- package/dist/RunSelector.test.js +45 -0
- package/dist/RunSelector.test.js.map +1 -0
- package/dist/SampleChart.test.d.ts +2 -0
- package/dist/SampleChart.test.d.ts.map +1 -0
- package/dist/SampleChart.test.js +48 -0
- package/dist/SampleChart.test.js.map +1 -0
- package/dist/TagFilter.test.d.ts +2 -0
- package/dist/TagFilter.test.d.ts.map +1 -0
- package/dist/TagFilter.test.js +106 -0
- package/dist/TagFilter.test.js.map +1 -0
- package/dist/VerdictBanner.test.d.ts +2 -0
- package/dist/VerdictBanner.test.d.ts.map +1 -0
- package/dist/VerdictBanner.test.js +56 -0
- package/dist/VerdictBanner.test.js.map +1 -0
- package/dist/chart-config.d.ts +100 -0
- package/dist/chart-config.d.ts.map +1 -0
- package/dist/chart-config.js +81 -0
- package/dist/chart-config.js.map +1 -0
- package/dist/colors.d.ts +11 -0
- package/dist/colors.d.ts.map +1 -0
- package/dist/colors.js +16 -0
- package/dist/colors.js.map +1 -0
- package/dist/comparison-transforms.d.ts +22 -0
- package/dist/comparison-transforms.d.ts.map +1 -0
- package/dist/comparison-transforms.js +20 -0
- package/dist/comparison-transforms.js.map +1 -0
- package/dist/comparison-transforms.test.d.ts +2 -0
- package/dist/comparison-transforms.test.d.ts.map +1 -0
- package/dist/comparison-transforms.test.js +75 -0
- package/dist/comparison-transforms.test.js.map +1 -0
- package/dist/components/ComparisonBar.d.ts +13 -0
- package/dist/components/ComparisonBar.d.ts.map +1 -0
- package/dist/components/ComparisonBar.js +94 -0
- package/dist/components/ComparisonBar.js.map +1 -0
- package/dist/components/ComparisonChart.d.ts +31 -0
- package/dist/components/ComparisonChart.d.ts.map +1 -0
- package/dist/components/ComparisonChart.js +118 -0
- package/dist/components/ComparisonChart.js.map +1 -0
- package/dist/components/ComparisonSummaryTable.d.ts +29 -0
- package/dist/components/ComparisonSummaryTable.d.ts.map +1 -0
- package/dist/components/ComparisonSummaryTable.js +41 -0
- package/dist/components/ComparisonSummaryTable.js.map +1 -0
- package/dist/components/DashboardToolbar.d.ts +21 -0
- package/dist/components/DashboardToolbar.d.ts.map +1 -0
- package/dist/components/DashboardToolbar.js +14 -0
- package/dist/components/DashboardToolbar.js.map +1 -0
- package/dist/components/DateRangeFilter.d.ts +19 -0
- package/dist/components/DateRangeFilter.d.ts.map +1 -0
- package/dist/components/DateRangeFilter.js +44 -0
- package/dist/components/DateRangeFilter.js.map +1 -0
- package/dist/components/HeroSection.d.ts +12 -0
- package/dist/components/HeroSection.d.ts.map +1 -0
- package/dist/components/HeroSection.js +6 -0
- package/dist/components/HeroSection.js.map +1 -0
- package/dist/components/Leaderboard.d.ts +9 -0
- package/dist/components/Leaderboard.d.ts.map +1 -0
- package/dist/components/Leaderboard.js +41 -0
- package/dist/components/Leaderboard.js.map +1 -0
- package/dist/components/MetricCard.d.ts +16 -0
- package/dist/components/MetricCard.d.ts.map +1 -0
- package/dist/components/MetricCard.js +25 -0
- package/dist/components/MetricCard.js.map +1 -0
- package/dist/components/MetricDetailView.d.ts +15 -0
- package/dist/components/MetricDetailView.d.ts.map +1 -0
- package/dist/components/MetricDetailView.js +11 -0
- package/dist/components/MetricDetailView.js.map +1 -0
- package/dist/components/MonitorSection.d.ts +21 -0
- package/dist/components/MonitorSection.d.ts.map +1 -0
- package/dist/components/MonitorSection.js +38 -0
- package/dist/components/MonitorSection.js.map +1 -0
- package/dist/components/OverviewGrid.d.ts +17 -0
- package/dist/components/OverviewGrid.d.ts.map +1 -0
- package/dist/components/OverviewGrid.js +15 -0
- package/dist/components/OverviewGrid.js.map +1 -0
- package/dist/components/RunSelector.d.ts +20 -0
- package/dist/components/RunSelector.d.ts.map +1 -0
- package/dist/components/RunSelector.js +53 -0
- package/dist/components/RunSelector.js.map +1 -0
- package/dist/components/RunTable.d.ts +13 -0
- package/dist/components/RunTable.d.ts.map +1 -0
- package/dist/components/RunTable.js +24 -0
- package/dist/components/RunTable.js.map +1 -0
- package/dist/components/SampleChart.d.ts +21 -0
- package/dist/components/SampleChart.d.ts.map +1 -0
- package/dist/components/SampleChart.js +77 -0
- package/dist/components/SampleChart.js.map +1 -0
- package/dist/components/TagFilter.d.ts +12 -0
- package/dist/components/TagFilter.d.ts.map +1 -0
- package/dist/components/TagFilter.js +59 -0
- package/dist/components/TagFilter.js.map +1 -0
- package/dist/components/TrendChart.d.ts +25 -0
- package/dist/components/TrendChart.d.ts.map +1 -0
- package/dist/components/TrendChart.js +95 -0
- package/dist/components/TrendChart.js.map +1 -0
- package/dist/components/VerdictBanner.d.ts +13 -0
- package/dist/components/VerdictBanner.d.ts.map +1 -0
- package/dist/components/VerdictBanner.js +22 -0
- package/dist/components/VerdictBanner.js.map +1 -0
- package/dist/dashboard-labels.d.ts +47 -0
- package/dist/dashboard-labels.d.ts.map +1 -0
- package/dist/dashboard-labels.js +44 -0
- package/dist/dashboard-labels.js.map +1 -0
- package/dist/dashboard-labels.test.d.ts +2 -0
- package/dist/dashboard-labels.test.d.ts.map +1 -0
- package/dist/dashboard-labels.test.js +34 -0
- package/dist/dashboard-labels.test.js.map +1 -0
- package/dist/dataset-transforms.d.ts +41 -0
- package/dist/dataset-transforms.d.ts.map +1 -0
- package/dist/dataset-transforms.js +132 -0
- package/dist/dataset-transforms.js.map +1 -0
- package/dist/dataset-transforms.test.d.ts +2 -0
- package/dist/dataset-transforms.test.d.ts.map +1 -0
- package/dist/dataset-transforms.test.js +208 -0
- package/dist/dataset-transforms.test.js.map +1 -0
- package/dist/date-range.test.d.ts +2 -0
- package/dist/date-range.test.d.ts.map +1 -0
- package/dist/date-range.test.js +116 -0
- package/dist/date-range.test.js.map +1 -0
- package/dist/embed.d.ts +45 -0
- package/dist/embed.d.ts.map +1 -0
- package/dist/embed.js +170 -0
- package/dist/embed.js.map +1 -0
- package/dist/embed.test.d.ts +2 -0
- package/dist/embed.test.d.ts.map +1 -0
- package/dist/embed.test.js +15 -0
- package/dist/embed.test.js.map +1 -0
- package/dist/fetch.d.ts +27 -0
- package/dist/fetch.d.ts.map +1 -0
- package/dist/fetch.js +73 -0
- package/dist/fetch.js.map +1 -0
- package/dist/fetch.test.d.ts +2 -0
- package/dist/fetch.test.d.ts.map +1 -0
- package/dist/fetch.test.js +75 -0
- package/dist/fetch.test.js.map +1 -0
- package/dist/format-utils.d.ts +48 -0
- package/dist/format-utils.d.ts.map +1 -0
- package/dist/format-utils.js +98 -0
- package/dist/format-utils.js.map +1 -0
- package/dist/format-utils.test.d.ts +2 -0
- package/dist/format-utils.test.d.ts.map +1 -0
- package/dist/format-utils.test.js +103 -0
- package/dist/format-utils.test.js.map +1 -0
- package/dist/hooks/useChartLifecycle.d.ts +20 -0
- package/dist/hooks/useChartLifecycle.d.ts.map +1 -0
- package/dist/hooks/useChartLifecycle.js +46 -0
- package/dist/hooks/useChartLifecycle.js.map +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +36 -0
- package/dist/index.js.map +1 -0
- package/dist/index.test.d.ts +2 -0
- package/dist/index.test.d.ts.map +1 -0
- package/dist/index.test.js +10 -0
- package/dist/index.test.js.map +1 -0
- package/dist/labels.d.ts +5 -0
- package/dist/labels.d.ts.map +1 -0
- package/dist/labels.js +41 -0
- package/dist/labels.js.map +1 -0
- package/dist/labels.test.d.ts +2 -0
- package/dist/labels.test.d.ts.map +1 -0
- package/dist/labels.test.js +28 -0
- package/dist/labels.test.js.map +1 -0
- package/dist/leaderboard.d.ts +29 -0
- package/dist/leaderboard.d.ts.map +1 -0
- package/dist/leaderboard.js +40 -0
- package/dist/leaderboard.js.map +1 -0
- package/dist/leaderboard.test.d.ts +2 -0
- package/dist/leaderboard.test.d.ts.map +1 -0
- package/dist/leaderboard.test.js +105 -0
- package/dist/leaderboard.test.js.map +1 -0
- package/dist/sample-utils.d.ts +4 -0
- package/dist/sample-utils.d.ts.map +1 -0
- package/dist/sample-utils.js +12 -0
- package/dist/sample-utils.js.map +1 -0
- package/dist/style.css +912 -0
- package/dist/theme.d.ts +12 -0
- package/dist/theme.d.ts.map +1 -0
- package/dist/theme.js +17 -0
- package/dist/theme.js.map +1 -0
- package/dist/utils.d.ts +37 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +63 -0
- package/dist/utils.js.map +1 -0
- package/dist/utils.test.d.ts +2 -0
- package/dist/utils.test.d.ts.map +1 -0
- package/dist/utils.test.js +196 -0
- package/dist/utils.test.js.map +1 -0
- package/package.json +46 -0
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { jsxs as _jsxs, jsx as _jsx } from "preact/jsx-runtime";
|
|
2
|
+
import { TrendChart } from "./TrendChart.js";
|
|
3
|
+
import { defaultMonitorMetricLabel } from "../labels.js";
|
|
4
|
+
function RunnerContextCard({ ctx }) {
|
|
5
|
+
const items = [];
|
|
6
|
+
if (ctx.runner_os)
|
|
7
|
+
items.push(["OS", ctx.runner_arch ? `${ctx.runner_os} (${ctx.runner_arch})` : ctx.runner_os]);
|
|
8
|
+
if (ctx.kernel)
|
|
9
|
+
items.push(["Kernel", ctx.kernel]);
|
|
10
|
+
if (ctx.cpu_model)
|
|
11
|
+
items.push(["CPU", ctx.cpu_count ? `${ctx.cpu_model} × ${ctx.cpu_count}` : ctx.cpu_model]);
|
|
12
|
+
if (ctx.total_memory_mb != null)
|
|
13
|
+
items.push(["Memory", `${Math.round(ctx.total_memory_mb / 1024)} GB`]);
|
|
14
|
+
if (ctx.poll_interval_ms)
|
|
15
|
+
items.push(["Poll interval", `${ctx.poll_interval_ms} ms`]);
|
|
16
|
+
if (items.length === 0)
|
|
17
|
+
return null;
|
|
18
|
+
return (_jsx("div", { class: "bk-monitor-context", children: items.map(([label, value]) => (_jsxs("span", { class: "bk-monitor-context__item", children: [_jsxs("strong", { children: [label, ":"] }), " ", value] }, label))) }));
|
|
19
|
+
}
|
|
20
|
+
export function MonitorSection({ monitorSeriesMap, index, maxPoints = 20, metricLabelFormatter, seriesNameFormatter, onMetricClick, selectedMetric, labels, }) {
|
|
21
|
+
if (monitorSeriesMap.size === 0)
|
|
22
|
+
return null;
|
|
23
|
+
// Find the most recent run that has a monitor context
|
|
24
|
+
const latestMonitorContext = index.runs.find((r) => r.monitor)?.monitor ?? null;
|
|
25
|
+
// Strip the _monitor/ prefix for display unless the formatter handles it
|
|
26
|
+
const displayLabel = (metric) => {
|
|
27
|
+
if (metricLabelFormatter)
|
|
28
|
+
return metricLabelFormatter(metric);
|
|
29
|
+
return defaultMonitorMetricLabel(metric);
|
|
30
|
+
};
|
|
31
|
+
return (_jsxs("section", { class: "bk-section", children: [_jsx("div", { class: "bk-section__header", children: _jsxs("div", { children: [_jsx("h3", { class: "bk-section__title", children: labels?.monitorTitle ?? "Runner metrics" }), _jsx("p", { class: "bk-section__description", children: labels?.monitorDescription ?? "Host and process telemetry from the Benchkit monitor action, kept visually secondary to the benchmark results." })] }) }), latestMonitorContext && _jsx(RunnerContextCard, { ctx: latestMonitorContext }), _jsx("div", { class: "bk-monitor-grid", children: [...monitorSeriesMap.entries()].map(([metric, sf]) => (_jsx("div", { role: "button", tabIndex: 0, onClick: () => onMetricClick?.(metric), onKeyDown: (e) => {
|
|
32
|
+
if (e.key === "Enter" || e.key === " ") {
|
|
33
|
+
e.preventDefault();
|
|
34
|
+
onMetricClick?.(metric);
|
|
35
|
+
}
|
|
36
|
+
}, class: `bk-card bk-card--interactive ${selectedMetric === metric ? "bk-card--selected" : ""}`, "aria-label": `View ${displayLabel(metric)} metric`, "aria-pressed": selectedMetric === metric, children: _jsx(TrendChart, { series: sf, title: displayLabel(metric), height: 156, maxPoints: maxPoints, seriesNameFormatter: seriesNameFormatter, compact: true, showLegend: false }) }, metric))) })] }));
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=MonitorSection.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"MonitorSection.js","sourceRoot":"","sources":["../../src/components/MonitorSection.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { SeriesFile, SeriesEntry } from "@benchkit/format";
|
|
2
|
+
import type { DashboardLabels } from "../dashboard-labels.js";
|
|
3
|
+
import type { RegressionResult } from "../utils.js";
|
|
4
|
+
export interface OverviewGridProps {
|
|
5
|
+
metricNames: string[];
|
|
6
|
+
seriesMap: Map<string, SeriesFile>;
|
|
7
|
+
seriesErrors: Map<string, string>;
|
|
8
|
+
activeFilters: Record<string, string>;
|
|
9
|
+
regressionMap: Map<string, RegressionResult[]>;
|
|
10
|
+
maxPoints: number;
|
|
11
|
+
formatMetric: (metric: string) => string;
|
|
12
|
+
seriesNameFormatter?: (name: string, entry: SeriesEntry) => string;
|
|
13
|
+
onMetricClick: (metric: string) => void;
|
|
14
|
+
labels: DashboardLabels;
|
|
15
|
+
}
|
|
16
|
+
export declare function OverviewGrid({ metricNames, seriesMap, seriesErrors, activeFilters, regressionMap, maxPoints, formatMetric, seriesNameFormatter, onMetricClick, labels, }: OverviewGridProps): import("preact").JSX.Element;
|
|
17
|
+
//# sourceMappingURL=OverviewGrid.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OverviewGrid.d.ts","sourceRoot":"","sources":["../../src/components/OverviewGrid.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAChE,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAE9D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAEpD,MAAM,WAAW,iBAAiB;IAChC,WAAW,EAAE,MAAM,EAAE,CAAC;IACtB,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAClC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,aAAa,EAAE,GAAG,CAAC,MAAM,EAAE,gBAAgB,EAAE,CAAC,CAAC;IAC/C,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IACzC,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,KAAK,MAAM,CAAC;IACnE,aAAa,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,MAAM,EAAE,eAAe,CAAC;CACzB;AAED,wBAAgB,YAAY,CAAC,EAC3B,WAAW,EACX,SAAS,EACT,YAAY,EACZ,aAAa,EACb,aAAa,EACb,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,MAAM,GACP,EAAE,iBAAiB,gCA+CnB"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { MetricCard } from "./MetricCard.js";
|
|
3
|
+
export function OverviewGrid({ metricNames, seriesMap, seriesErrors, activeFilters, regressionMap, maxPoints, formatMetric, seriesNameFormatter, onMetricClick, labels, }) {
|
|
4
|
+
return (_jsxs("section", { class: "bk-section", children: [_jsx("div", { class: "bk-section__header", children: _jsx("div", { children: _jsx("h3", { class: "bk-section__title", children: labels.primaryMetricsTitle }) }) }), _jsx("div", { class: "bk-overview-grid", children: metricNames.map((metric) => {
|
|
5
|
+
const metricErr = seriesErrors.get(metric);
|
|
6
|
+
if (metricErr) {
|
|
7
|
+
return (_jsxs("div", { class: "bk-card", children: [_jsxs("div", { class: "bk-card__top", children: [_jsxs("div", { children: [_jsx("h4", { class: "bk-card__title", children: formatMetric(metric) }), _jsx("p", { class: "bk-card__hint", children: labels.metricLoadHint })] }), _jsx("span", { class: "bk-badge bk-badge--danger", children: labels.loadErrorBadge })] }), _jsx("p", { class: "bk-muted", children: metricErr })] }, metric));
|
|
8
|
+
}
|
|
9
|
+
const sf = seriesMap.get(metric);
|
|
10
|
+
if (!sf)
|
|
11
|
+
return null;
|
|
12
|
+
return (_jsx(MetricCard, { metric: metric, seriesFile: sf, activeFilters: activeFilters, regressions: regressionMap.get(metric) ?? [], maxPoints: maxPoints, formatMetric: formatMetric, seriesNameFormatter: seriesNameFormatter, onClick: onMetricClick, labels: labels }, metric));
|
|
13
|
+
}) })] }));
|
|
14
|
+
}
|
|
15
|
+
//# sourceMappingURL=OverviewGrid.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"OverviewGrid.js","sourceRoot":"","sources":["../../src/components/OverviewGrid.tsx"],"names":[],"mappings":";AAEA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAgB7C,MAAM,UAAU,YAAY,CAAC,EAC3B,WAAW,EACX,SAAS,EACT,YAAY,EACZ,aAAa,EACb,aAAa,EACb,SAAS,EACT,YAAY,EACZ,mBAAmB,EACnB,aAAa,EACb,MAAM,GACY;IAClB,OAAO,CACL,mBAAS,KAAK,EAAC,YAAY,aACzB,cAAK,KAAK,EAAC,oBAAoB,YAC7B,wBACE,aAAI,KAAK,EAAC,mBAAmB,YAAE,MAAM,CAAC,mBAAmB,GAAM,GAC3D,GACF,EACN,cAAK,KAAK,EAAC,kBAAkB,YAC1B,WAAW,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,EAAE;oBAC1B,MAAM,SAAS,GAAG,YAAY,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBAC3C,IAAI,SAAS,EAAE,CAAC;wBACd,OAAO,CACL,eAAkB,KAAK,EAAC,SAAS,aAC/B,eAAK,KAAK,EAAC,cAAc,aACvB,0BACE,aAAI,KAAK,EAAC,gBAAgB,YAAE,YAAY,CAAC,MAAM,CAAC,GAAM,EACtD,YAAG,KAAK,EAAC,eAAe,YAAE,MAAM,CAAC,cAAc,GAAK,IAChD,EACN,eAAM,KAAK,EAAC,2BAA2B,YAAE,MAAM,CAAC,cAAc,GAAQ,IAClE,EACN,YAAG,KAAK,EAAC,UAAU,YAAE,SAAS,GAAK,KAR3B,MAAM,CASV,CACP,CAAC;oBACJ,CAAC;oBAED,MAAM,EAAE,GAAG,SAAS,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC;oBACjC,IAAI,CAAC,EAAE;wBAAE,OAAO,IAAI,CAAC;oBAErB,OAAO,CACL,KAAC,UAAU,IAET,MAAM,EAAE,MAAM,EACd,UAAU,EAAE,EAAE,EACd,aAAa,EAAE,aAAa,EAC5B,WAAW,EAAE,aAAa,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,EAAE,EAC5C,SAAS,EAAE,SAAS,EACpB,YAAY,EAAE,YAAY,EAC1B,mBAAmB,EAAE,mBAAmB,EACxC,OAAO,EAAE,aAAa,EACtB,MAAM,EAAE,MAAM,IATT,MAAM,CAUX,CACH,CAAC;gBACJ,CAAC,CAAC,GACE,IACE,CACX,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { IndexFile, PrIndexEntry, RefIndexEntry } from "@benchkit/format";
|
|
2
|
+
export interface RunSelectorProps {
|
|
3
|
+
prIndex?: PrIndexEntry[];
|
|
4
|
+
refIndex?: RefIndexEntry[];
|
|
5
|
+
index: IndexFile;
|
|
6
|
+
selectedRunId?: string;
|
|
7
|
+
baselineRunId?: string;
|
|
8
|
+
onSelectRun: (runId: string) => void;
|
|
9
|
+
/** Called when the user picks a baseline. If omitted, baseline is display-only. */
|
|
10
|
+
onSelectBaseline?: (runId: string) => void;
|
|
11
|
+
/** Label for the PR list heading. Default: "Pull Requests" */
|
|
12
|
+
prHeading?: string;
|
|
13
|
+
/** Label for the ref/run list heading. Default: "Runs" */
|
|
14
|
+
runHeading?: string;
|
|
15
|
+
/** Custom ref formatter. Default: {@link formatRef} from format-utils. */
|
|
16
|
+
formatRef?: (ref: string) => string;
|
|
17
|
+
class?: string;
|
|
18
|
+
}
|
|
19
|
+
export declare function RunSelector({ prIndex, refIndex, index, selectedRunId, baselineRunId, onSelectRun, onSelectBaseline, prHeading, runHeading, formatRef, class: className, }: RunSelectorProps): import("preact").JSX.Element;
|
|
20
|
+
//# sourceMappingURL=RunSelector.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunSelector.d.ts","sourceRoot":"","sources":["../../src/components/RunSelector.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EACV,SAAS,EACT,YAAY,EACZ,aAAa,EACd,MAAM,kBAAkB,CAAC;AAU1B,MAAM,WAAW,gBAAgB;IAC/B,OAAO,CAAC,EAAE,YAAY,EAAE,CAAC;IACzB,QAAQ,CAAC,EAAE,aAAa,EAAE,CAAC;IAC3B,KAAK,EAAE,SAAS,CAAC;IACjB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACrC,mFAAmF;IACnF,gBAAgB,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAC3C,8DAA8D;IAC9D,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,0DAA0D;IAC1D,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,0EAA0E;IAC1E,SAAS,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,MAAM,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,QAAQ,EACR,KAAK,EACL,aAAa,EACb,aAAa,EACb,WAAW,EACX,gBAAgB,EAChB,SAA2B,EAC3B,UAAmB,EACnB,SAA4B,EAC5B,KAAK,EAAE,SAAS,GACjB,EAAE,gBAAgB,gCA+BlB"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { formatRef as defaultFormatRef, formatTimestamp, shortCommit, } from "../format-utils.js";
|
|
3
|
+
/** Maximum number of recent runs shown in ref-fallback mode. */
|
|
4
|
+
const MAX_RECENT_RUNS = 20;
|
|
5
|
+
export function RunSelector({ prIndex, refIndex, index, selectedRunId, baselineRunId, onSelectRun, onSelectBaseline, prHeading = "Pull Requests", runHeading = "Runs", formatRef = defaultFormatRef, class: className, }) {
|
|
6
|
+
const hasPrs = prIndex && prIndex.length > 0;
|
|
7
|
+
const sortedPrs = hasPrs
|
|
8
|
+
? [...prIndex].sort((a, b) => b.latestTimestamp.localeCompare(a.latestTimestamp))
|
|
9
|
+
: undefined;
|
|
10
|
+
return (_jsx("div", { class: ["bk-run-selector", className].filter(Boolean).join(" "), children: hasPrs ? (_jsx(PrList, { prIndex: sortedPrs, selectedRunId: selectedRunId, baselineRunId: baselineRunId, onSelectRun: onSelectRun, onSelectBaseline: onSelectBaseline, heading: prHeading })) : (_jsx(RefList, { refIndex: refIndex, index: index, selectedRunId: selectedRunId, baselineRunId: baselineRunId, onSelectRun: onSelectRun, onSelectBaseline: onSelectBaseline, heading: runHeading, formatRef: formatRef })) }));
|
|
11
|
+
}
|
|
12
|
+
function PrList({ prIndex, selectedRunId, baselineRunId, onSelectRun, onSelectBaseline, heading, }) {
|
|
13
|
+
return (_jsxs("div", { class: "bk-run-selector__list", children: [_jsx("div", { class: "bk-run-selector__heading", children: heading }), prIndex.map((pr) => {
|
|
14
|
+
const isSelected = pr.latestRunId === selectedRunId;
|
|
15
|
+
const isBaseline = pr.latestRunId === baselineRunId;
|
|
16
|
+
return (_jsxs("button", { class: [
|
|
17
|
+
"bk-run-selector__item",
|
|
18
|
+
isSelected && "bk-run-selector__item--selected",
|
|
19
|
+
isBaseline && "bk-run-selector__item--baseline",
|
|
20
|
+
]
|
|
21
|
+
.filter(Boolean)
|
|
22
|
+
.join(" "), onClick: () => onSelectRun(pr.latestRunId), type: "button", children: [_jsxs("span", { class: "bk-run-selector__primary", children: ["PR #", pr.prNumber] }), _jsxs("span", { class: "bk-run-selector__meta", children: [_jsx("code", { class: "bk-code", children: shortCommit(pr.latestCommit) }), " · ", formatTimestamp(pr.latestTimestamp), pr.runCount > 1 && (_jsxs("span", { class: "bk-muted", children: [" \u00B7 ", pr.runCount, " runs"] }))] }), isSelected && _jsx("span", { class: "bk-badge bk-badge--accent", children: "selected" }), isBaseline && _jsx("span", { class: "bk-badge bk-badge--muted", children: "baseline" }), onSelectBaseline && !isBaseline && (_jsx("button", { type: "button", class: "bk-link-button bk-run-selector__baseline-btn", onClick: (e) => { e.stopPropagation(); onSelectBaseline(pr.latestRunId); }, children: "set baseline" }))] }, pr.prNumber));
|
|
23
|
+
})] }));
|
|
24
|
+
}
|
|
25
|
+
function RefList({ refIndex, index, selectedRunId, baselineRunId, onSelectRun, onSelectBaseline, heading, formatRef, }) {
|
|
26
|
+
const items = refIndex && refIndex.length > 0
|
|
27
|
+
? refIndex.map((r) => ({
|
|
28
|
+
id: r.latestRunId,
|
|
29
|
+
label: formatRef(r.ref),
|
|
30
|
+
commit: r.latestCommit,
|
|
31
|
+
timestamp: r.latestTimestamp,
|
|
32
|
+
runCount: r.runCount,
|
|
33
|
+
}))
|
|
34
|
+
: index.runs.slice(0, MAX_RECENT_RUNS).map((r) => ({
|
|
35
|
+
id: r.id,
|
|
36
|
+
label: r.ref ? formatRef(r.ref) : r.id,
|
|
37
|
+
commit: r.commit,
|
|
38
|
+
timestamp: r.timestamp,
|
|
39
|
+
runCount: 1,
|
|
40
|
+
}));
|
|
41
|
+
return (_jsxs("div", { class: "bk-run-selector__list", children: [_jsx("div", { class: "bk-run-selector__heading", children: heading }), items.map((item) => {
|
|
42
|
+
const isSelected = item.id === selectedRunId;
|
|
43
|
+
const isBaseline = item.id === baselineRunId;
|
|
44
|
+
return (_jsxs("button", { class: [
|
|
45
|
+
"bk-run-selector__item",
|
|
46
|
+
isSelected && "bk-run-selector__item--selected",
|
|
47
|
+
isBaseline && "bk-run-selector__item--baseline",
|
|
48
|
+
]
|
|
49
|
+
.filter(Boolean)
|
|
50
|
+
.join(" "), onClick: () => onSelectRun(item.id), type: "button", children: [_jsx("span", { class: "bk-run-selector__primary", children: item.label }), _jsxs("span", { class: "bk-run-selector__meta", children: [_jsx("code", { class: "bk-code", children: shortCommit(item.commit) }), " · ", formatTimestamp(item.timestamp), item.runCount > 1 && (_jsxs("span", { class: "bk-muted", children: [" \u00B7 ", item.runCount, " runs"] }))] }), isSelected && _jsx("span", { class: "bk-badge bk-badge--accent", children: "selected" }), isBaseline && _jsx("span", { class: "bk-badge bk-badge--muted", children: "baseline" }), onSelectBaseline && !isBaseline && (_jsx("button", { type: "button", class: "bk-link-button bk-run-selector__baseline-btn", onClick: (e) => { e.stopPropagation(); onSelectBaseline(item.id); }, children: "set baseline" }))] }, item.id));
|
|
51
|
+
}), items.length === 0 && (_jsx("div", { class: "bk-empty", children: "No runs available." }))] }));
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=RunSelector.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunSelector.js","sourceRoot":"","sources":["../../src/components/RunSelector.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { IndexFile, RunEntry } from "@benchkit/format";
|
|
2
|
+
import type { DashboardLabels } from "../dashboard-labels.js";
|
|
3
|
+
export interface RunTableProps {
|
|
4
|
+
index: IndexFile;
|
|
5
|
+
maxRows?: number;
|
|
6
|
+
onSelectRun?: (runId: string) => void;
|
|
7
|
+
/** Link commits to GitHub or other VCS */
|
|
8
|
+
commitHref?: (commit: string, run: RunEntry) => string | undefined;
|
|
9
|
+
class?: string;
|
|
10
|
+
labels?: DashboardLabels;
|
|
11
|
+
}
|
|
12
|
+
export declare function RunTable({ index, maxRows, onSelectRun, commitHref, class: className, labels }: RunTableProps): import("preact").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=RunTable.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunTable.d.ts","sourceRoot":"","sources":["../../src/components/RunTable.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AAC5D,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAG9D,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,SAAS,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IACtC,0CAA0C;IAC1C,UAAU,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,QAAQ,KAAK,MAAM,GAAG,SAAS,CAAC;IACnE,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,eAAe,CAAC;CAC1B;AAED,wBAAgB,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAE,EAAE,aAAa,gCA2D5G"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { formatRef } from "../format-utils.js";
|
|
3
|
+
export function RunTable({ index, maxRows, onSelectRun, commitHref, class: className, labels }) {
|
|
4
|
+
const runs = maxRows ? index.runs.slice(0, maxRows) : index.runs;
|
|
5
|
+
return (_jsx("div", { class: ["bk-table-shell", className].filter(Boolean).join(" "), children: _jsx("div", { class: "bk-table-shell__scroll", children: _jsxs("table", { class: "bk-table", children: [_jsx("caption", { class: "bk-sr-only", children: "Recent benchmark runs" }), _jsx("thead", { children: _jsxs("tr", { children: [_jsx("th", { scope: "col", children: labels?.runColumn ?? "Run" }), _jsx("th", { scope: "col", children: labels?.timeColumn ?? "Time" }), _jsx("th", { scope: "col", children: labels?.commitColumn ?? "Commit" }), _jsx("th", { scope: "col", children: labels?.refColumn ?? "Ref" }), _jsx("th", { scope: "col", class: "bk-table__numeric", children: labels?.benchmarksColumn ?? "Benchmarks" }), _jsx("th", { scope: "col", children: labels?.metricsColumn ?? "Metrics" })] }) }), _jsx("tbody", { children: runs.map((run) => (_jsxs("tr", { style: { cursor: onSelectRun ? "pointer" : "default" }, onClick: () => onSelectRun?.(run.id), children: [_jsx("td", { children: _jsx("code", { class: "bk-code", children: run.id }) }), _jsx("td", { children: formatTime(run.timestamp) }), _jsx("td", { children: run.commit ? ((() => {
|
|
6
|
+
const href = commitHref?.(run.commit, run);
|
|
7
|
+
const code = _jsx("code", { class: "bk-code", children: run.commit.slice(0, 8) });
|
|
8
|
+
return href ? _jsx("a", { href: href, target: "_blank", rel: "noopener noreferrer", children: code }) : code;
|
|
9
|
+
})()) : (_jsx("span", { class: "bk-muted", children: "\u2014" })) }), _jsx("td", { children: formatRef(run.ref) }), _jsx("td", { class: "bk-table__numeric", children: run.benchmarks ?? "—" }), _jsx("td", { class: "bk-muted", children: run.metrics?.join(", ") ?? "—" })] }, run.id))) }), maxRows && index.runs.length > maxRows && (_jsx("tfoot", { children: _jsx("tr", { children: _jsxs("td", { colSpan: 6, class: "bk-muted", children: ["Showing ", maxRows, " of ", index.runs.length, " runs"] }) }) }))] }) }) }));
|
|
10
|
+
}
|
|
11
|
+
function formatTime(ts) {
|
|
12
|
+
try {
|
|
13
|
+
return new Date(ts).toLocaleString(undefined, {
|
|
14
|
+
month: "short",
|
|
15
|
+
day: "numeric",
|
|
16
|
+
hour: "2-digit",
|
|
17
|
+
minute: "2-digit",
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return ts;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
//# sourceMappingURL=RunTable.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"RunTable.js","sourceRoot":"","sources":["../../src/components/RunTable.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Sample } from "@benchkit/format";
|
|
2
|
+
export interface SampleChartProps {
|
|
3
|
+
/** Intra-run time-series data points. */
|
|
4
|
+
samples: Sample[];
|
|
5
|
+
/** Metric keys to plot. Defaults to all keys found in the samples. */
|
|
6
|
+
metrics?: string[];
|
|
7
|
+
height?: number;
|
|
8
|
+
title?: string;
|
|
9
|
+
subtitle?: string;
|
|
10
|
+
/** Compact "sparkline" mode for embedding in summary cards. */
|
|
11
|
+
compact?: boolean;
|
|
12
|
+
/** Stroke width for trend lines. */
|
|
13
|
+
lineWidth?: number;
|
|
14
|
+
/** Custom label for a metric key. */
|
|
15
|
+
metricLabelFormatter?: (metric: string) => string;
|
|
16
|
+
showLegend?: boolean;
|
|
17
|
+
/** CSS class name */
|
|
18
|
+
class?: string;
|
|
19
|
+
}
|
|
20
|
+
export declare function SampleChart({ samples, metrics, height, title, subtitle, compact, lineWidth, metricLabelFormatter, showLegend, class: className, }: SampleChartProps): import("preact").JSX.Element;
|
|
21
|
+
//# sourceMappingURL=SampleChart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SampleChart.d.ts","sourceRoot":"","sources":["../../src/components/SampleChart.tsx"],"names":[],"mappings":"AAoBA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,kBAAkB,CAAC;AAO/C,MAAM,WAAW,gBAAgB;IAC/B,yCAAyC;IACzC,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,sEAAsE;IACtE,OAAO,CAAC,EAAE,MAAM,EAAE,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,+DAA+D;IAC/D,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,oCAAoC;IACpC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,qCAAqC;IACrC,oBAAoB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,MAAM,CAAC;IAClD,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,wBAAgB,WAAW,CAAC,EAC1B,OAAO,EACP,OAAO,EACP,MAAY,EACZ,KAAK,EACL,QAAQ,EACR,OAAe,EACf,SAAS,EACT,oBAAoB,EACpB,UAAiB,EACjB,KAAK,EAAE,SAAS,GACjB,EAAE,gBAAgB,gCAkHlB"}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { useMemo } from "preact/hooks";
|
|
3
|
+
import { formatValue } from "../format-utils.js";
|
|
4
|
+
import { sharedTooltipStyle, layoutPadding, baseLineOptions, yAxisConfig, linearXAxis, } from "../chart-config.js";
|
|
5
|
+
import { Chart, LineController, LineElement, PointElement, LinearScale, Tooltip, Legend, } from "chart.js";
|
|
6
|
+
import { COLORS } from "../colors.js";
|
|
7
|
+
import { useChartLifecycle } from "../hooks/useChartLifecycle.js";
|
|
8
|
+
import { extractSampleMetrics } from "../sample-utils.js";
|
|
9
|
+
Chart.register(LineController, LineElement, PointElement, LinearScale, Tooltip, Legend);
|
|
10
|
+
export function SampleChart({ samples, metrics, height = 300, title, subtitle, compact = false, lineWidth, metricLabelFormatter, showLegend = true, class: className, }) {
|
|
11
|
+
const resolvedMetrics = useMemo(() => {
|
|
12
|
+
if (metrics && metrics.length > 0)
|
|
13
|
+
return metrics;
|
|
14
|
+
return extractSampleMetrics(samples);
|
|
15
|
+
}, [samples, metrics]);
|
|
16
|
+
const datasets = useMemo(() => {
|
|
17
|
+
return resolvedMetrics.map((metric, idx) => {
|
|
18
|
+
const color = COLORS[idx % COLORS.length];
|
|
19
|
+
const label = metricLabelFormatter ? metricLabelFormatter(metric) : metric;
|
|
20
|
+
return {
|
|
21
|
+
label,
|
|
22
|
+
data: samples.map((s) => ({ x: s.t, y: s[metric] ?? null })),
|
|
23
|
+
borderColor: color,
|
|
24
|
+
backgroundColor: `${color}22`,
|
|
25
|
+
fill: resolvedMetrics.length === 1,
|
|
26
|
+
tension: 0,
|
|
27
|
+
borderWidth: lineWidth ?? (compact ? 1.5 : 1.75),
|
|
28
|
+
clip: 8,
|
|
29
|
+
spanGaps: true,
|
|
30
|
+
pointRadius: compact ? 1.75 : 2.5,
|
|
31
|
+
pointHoverRadius: compact ? 4 : 6,
|
|
32
|
+
pointBackgroundColor: color,
|
|
33
|
+
pointBorderColor: color,
|
|
34
|
+
};
|
|
35
|
+
});
|
|
36
|
+
}, [resolvedMetrics, samples, metricLabelFormatter, compact, lineWidth]);
|
|
37
|
+
const { canvasRef, wrapperRef } = useChartLifecycle((theme) => {
|
|
38
|
+
if (datasets.length === 0 || samples.length === 0)
|
|
39
|
+
return null;
|
|
40
|
+
const options = {
|
|
41
|
+
...baseLineOptions(),
|
|
42
|
+
layout: { padding: layoutPadding(compact) },
|
|
43
|
+
interaction: { mode: "nearest", intersect: false },
|
|
44
|
+
plugins: {
|
|
45
|
+
legend: { display: false },
|
|
46
|
+
tooltip: {
|
|
47
|
+
...sharedTooltipStyle(theme),
|
|
48
|
+
callbacks: {
|
|
49
|
+
title: (items) => `t = ${items[0]?.label ?? ""}s`,
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
scales: {
|
|
54
|
+
x: linearXAxis(theme, {
|
|
55
|
+
title: "Elapsed time (s)",
|
|
56
|
+
showTitle: !compact,
|
|
57
|
+
maxTicksLimit: compact ? 4 : 7,
|
|
58
|
+
tickCallback: (value) => `${value}s`,
|
|
59
|
+
}),
|
|
60
|
+
y: yAxisConfig(theme, {
|
|
61
|
+
showTitle: !compact && resolvedMetrics.length === 1,
|
|
62
|
+
title: resolvedMetrics[0] ?? "",
|
|
63
|
+
maxTicksLimit: compact ? 4 : 6,
|
|
64
|
+
tickCallback: (value) => formatValue(Number(value), compact),
|
|
65
|
+
}),
|
|
66
|
+
},
|
|
67
|
+
};
|
|
68
|
+
return { type: "line", data: { datasets }, options };
|
|
69
|
+
}, [compact, datasets, samples.length, resolvedMetrics]);
|
|
70
|
+
const isEmpty = samples.length === 0 || resolvedMetrics.length === 0;
|
|
71
|
+
return (_jsxs("div", { ref: wrapperRef, class: ["bk-chart-panel", className].filter(Boolean).join(" "), children: [(title || subtitle) && (_jsx("div", { class: "bk-chart-panel__header", children: _jsxs("div", { children: [title && _jsx("h3", { class: "bk-chart-panel__title", children: title }), subtitle && _jsx("p", { class: "bk-chart-panel__subtitle", children: subtitle })] }) })), showLegend && !compact && resolvedMetrics.length > 1 && (_jsx("div", { class: "bk-chart-legend", children: resolvedMetrics.map((metric, idx) => {
|
|
72
|
+
const color = COLORS[idx % COLORS.length];
|
|
73
|
+
const label = metricLabelFormatter ? metricLabelFormatter(metric) : metric;
|
|
74
|
+
return (_jsxs("span", { class: "bk-chart-legend__item", title: label, children: [_jsx("span", { class: "bk-chart-legend__swatch", style: { background: color } }), _jsx("span", { class: "bk-chart-legend__label", children: label })] }, metric));
|
|
75
|
+
}) })), _jsx("div", { class: "bk-chart-panel__canvas", style: { height: `${height}px` }, children: isEmpty ? (_jsx("div", { class: "bk-chart-panel__empty", children: _jsxs("div", { children: [_jsx("strong", { children: "No sample data." }), _jsx("div", { children: "No intra-run time-series samples are available for this benchmark." })] }) })) : (_jsx("canvas", { ref: canvasRef, role: "img", "aria-label": title ?? "Sample chart", children: title ?? "Sample chart" })) })] }));
|
|
76
|
+
}
|
|
77
|
+
//# sourceMappingURL=SampleChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SampleChart.js","sourceRoot":"","sources":["../../src/components/SampleChart.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { SeriesFile } from "@benchkit/format";
|
|
2
|
+
/** Extracts all unique tag keys and their possible values from a collection of SeriesFiles. */
|
|
3
|
+
export declare function extractTags(seriesMap: Map<string, SeriesFile>): Record<string, string[]>;
|
|
4
|
+
/** Filters a SeriesFile so only entries matching all active filters are included. */
|
|
5
|
+
export declare function filterSeriesFile(sf: SeriesFile, activeFilters: Record<string, string>): SeriesFile;
|
|
6
|
+
export interface TagFilterProps {
|
|
7
|
+
seriesMap: Map<string, SeriesFile>;
|
|
8
|
+
activeFilters: Record<string, string>;
|
|
9
|
+
onFilterChange: (filters: Record<string, string>) => void;
|
|
10
|
+
}
|
|
11
|
+
export declare function TagFilter({ seriesMap, activeFilters, onFilterChange }: TagFilterProps): import("preact").JSX.Element | null;
|
|
12
|
+
//# sourceMappingURL=TagFilter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagFilter.d.ts","sourceRoot":"","sources":["../../src/components/TagFilter.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAEnD,+FAA+F;AAC/F,wBAAgB,WAAW,CAAC,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,EAAE,CAAC,CAiBxF;AAED,qFAAqF;AACrF,wBAAgB,gBAAgB,CAAC,EAAE,EAAE,UAAU,EAAE,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,UAAU,CASlG;AAED,MAAM,WAAW,cAAc;IAC7B,SAAS,EAAE,GAAG,CAAC,MAAM,EAAE,UAAU,CAAC,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,cAAc,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,CAAC;CAC3D;AAED,wBAAgB,SAAS,CAAC,EAAE,SAAS,EAAE,aAAa,EAAE,cAAc,EAAE,EAAE,cAAc,uCAuDrF"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
/** Extracts all unique tag keys and their possible values from a collection of SeriesFiles. */
|
|
3
|
+
export function extractTags(seriesMap) {
|
|
4
|
+
const tagMap = {};
|
|
5
|
+
for (const sf of seriesMap.values()) {
|
|
6
|
+
for (const entry of Object.values(sf.series)) {
|
|
7
|
+
if (entry.tags) {
|
|
8
|
+
for (const [key, value] of Object.entries(entry.tags)) {
|
|
9
|
+
if (!tagMap[key])
|
|
10
|
+
tagMap[key] = new Set();
|
|
11
|
+
tagMap[key].add(value);
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
const result = {};
|
|
17
|
+
for (const [key, values] of Object.entries(tagMap)) {
|
|
18
|
+
result[key] = [...values].sort();
|
|
19
|
+
}
|
|
20
|
+
return result;
|
|
21
|
+
}
|
|
22
|
+
/** Filters a SeriesFile so only entries matching all active filters are included. */
|
|
23
|
+
export function filterSeriesFile(sf, activeFilters) {
|
|
24
|
+
if (Object.keys(activeFilters).length === 0)
|
|
25
|
+
return sf;
|
|
26
|
+
const filtered = {};
|
|
27
|
+
for (const [name, entry] of Object.entries(sf.series)) {
|
|
28
|
+
const tags = entry.tags ?? {};
|
|
29
|
+
const matches = Object.entries(activeFilters).every(([k, v]) => tags[k] === v);
|
|
30
|
+
if (matches)
|
|
31
|
+
filtered[name] = entry;
|
|
32
|
+
}
|
|
33
|
+
return { ...sf, series: filtered };
|
|
34
|
+
}
|
|
35
|
+
export function TagFilter({ seriesMap, activeFilters, onFilterChange }) {
|
|
36
|
+
const availableTags = extractTags(seriesMap);
|
|
37
|
+
const tagKeys = Object.keys(availableTags);
|
|
38
|
+
if (tagKeys.length === 0)
|
|
39
|
+
return null;
|
|
40
|
+
function toggle(key, value) {
|
|
41
|
+
const next = { ...activeFilters };
|
|
42
|
+
if (next[key] === value) {
|
|
43
|
+
delete next[key];
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
next[key] = value;
|
|
47
|
+
}
|
|
48
|
+
onFilterChange(next);
|
|
49
|
+
}
|
|
50
|
+
function clearAll() {
|
|
51
|
+
onFilterChange({});
|
|
52
|
+
}
|
|
53
|
+
const hasActiveFilters = Object.keys(activeFilters).length > 0;
|
|
54
|
+
return (_jsxs("div", { class: "bk-toolbar__row", children: [tagKeys.map((key) => (_jsxs("div", { class: "bk-toolbar__group", children: [_jsx("span", { class: "bk-toolbar__label", children: key }), availableTags[key].map((value) => {
|
|
55
|
+
const active = activeFilters[key] === value;
|
|
56
|
+
return (_jsx("button", { type: "button", onClick: () => toggle(key, value), class: `bk-chip ${active ? "bk-chip--active" : ""}`, "aria-pressed": active, "aria-label": `${key}: ${value}`, children: value }, value));
|
|
57
|
+
})] }, key))), hasActiveFilters && (_jsx("button", { type: "button", onClick: clearAll, class: "bk-chip bk-link-button--danger", children: "Clear filters" }))] }));
|
|
58
|
+
}
|
|
59
|
+
//# sourceMappingURL=TagFilter.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TagFilter.js","sourceRoot":"","sources":["../../src/components/TagFilter.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import "chartjs-adapter-date-fns";
|
|
2
|
+
import type { SeriesFile, SeriesEntry } from "@benchkit/format";
|
|
3
|
+
import type { RegressionResult } from "../utils.js";
|
|
4
|
+
export interface TrendChartProps {
|
|
5
|
+
series: SeriesFile;
|
|
6
|
+
height?: number;
|
|
7
|
+
title?: string;
|
|
8
|
+
subtitle?: string;
|
|
9
|
+
summary?: string;
|
|
10
|
+
compact?: boolean;
|
|
11
|
+
/** Stroke width for trend lines. Defaults to a thinner metrics-friendly width. */
|
|
12
|
+
lineWidth?: number;
|
|
13
|
+
/** Max points per series to display (default: all) */
|
|
14
|
+
maxPoints?: number;
|
|
15
|
+
/** Custom series name renderer */
|
|
16
|
+
seriesNameFormatter?: (name: string, entry: SeriesEntry) => string;
|
|
17
|
+
showLegend?: boolean;
|
|
18
|
+
showSeriesCount?: boolean;
|
|
19
|
+
/** CSS class name */
|
|
20
|
+
class?: string;
|
|
21
|
+
/** Regression results to highlight on the chart (last data point of each flagged series). */
|
|
22
|
+
regressions?: RegressionResult[];
|
|
23
|
+
}
|
|
24
|
+
export declare function TrendChart({ series, height, title, subtitle, summary, compact, lineWidth, maxPoints, seriesNameFormatter, showLegend, showSeriesCount, class: className, regressions, }: TrendChartProps): import("preact").JSX.Element;
|
|
25
|
+
//# sourceMappingURL=TrendChart.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrendChart.d.ts","sourceRoot":"","sources":["../../src/components/TrendChart.tsx"],"names":[],"mappings":"AAuBA,OAAO,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAE,UAAU,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAGhE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAapD,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,kFAAkF;IAClF,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,sDAAsD;IACtD,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kCAAkC;IAClC,mBAAmB,CAAC,EAAE,CAAC,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,WAAW,KAAK,MAAM,CAAC;IACnE,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,eAAe,CAAC,EAAE,OAAO,CAAC;IAC1B,qBAAqB;IACrB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,6FAA6F;IAC7F,WAAW,CAAC,EAAE,gBAAgB,EAAE,CAAC;CAClC;AAED,wBAAgB,UAAU,CAAC,EACzB,MAAM,EACN,MAAY,EACZ,KAAK,EACL,QAAQ,EACR,OAAO,EACP,OAAe,EACf,SAAS,EACT,SAAS,EACT,mBAAmB,EACnB,UAAiB,EACjB,eAAsB,EACtB,KAAK,EAAE,SAAS,EAChB,WAAW,GACZ,EAAE,eAAe,gCA0IjB"}
|
|
@@ -0,0 +1,95 @@
|
|
|
1
|
+
import { jsx as _jsx, jsxs as _jsxs } from "preact/jsx-runtime";
|
|
2
|
+
import { useMemo } from "preact/hooks";
|
|
3
|
+
import { formatValue } from "../format-utils.js";
|
|
4
|
+
import { REGRESSION_COLOR, REGRESSION_BORDER_COLOR } from "../colors.js";
|
|
5
|
+
import { sharedTooltipStyle, layoutPadding, baseLineOptions, yAxisConfig, timeXAxis, } from "../chart-config.js";
|
|
6
|
+
import { Chart, LineController, LineElement, PointElement, LinearScale, TimeScale, Tooltip, Legend, Filler, } from "chart.js";
|
|
7
|
+
import "chartjs-adapter-date-fns";
|
|
8
|
+
import { COLORS } from "../colors.js";
|
|
9
|
+
import { useChartLifecycle } from "../hooks/useChartLifecycle.js";
|
|
10
|
+
Chart.register(LineController, LineElement, PointElement, LinearScale, TimeScale, Tooltip, Legend, Filler);
|
|
11
|
+
export function TrendChart({ series, height = 300, title, subtitle, summary, compact = false, lineWidth, maxPoints, seriesNameFormatter, showLegend = true, showSeriesCount = true, class: className, regressions, }) {
|
|
12
|
+
const entries = useMemo(() => {
|
|
13
|
+
return Object.entries(series.series)
|
|
14
|
+
.map(([name, entry], idx) => {
|
|
15
|
+
const points = maxPoints && entry.points.length > maxPoints
|
|
16
|
+
? entry.points.slice(-maxPoints)
|
|
17
|
+
: entry.points;
|
|
18
|
+
if (points.length === 0)
|
|
19
|
+
return null;
|
|
20
|
+
return {
|
|
21
|
+
name,
|
|
22
|
+
entry,
|
|
23
|
+
points,
|
|
24
|
+
color: COLORS[idx % COLORS.length],
|
|
25
|
+
label: seriesNameFormatter ? seriesNameFormatter(name, entry) : name,
|
|
26
|
+
isRegressed: regressions?.some((result) => result.seriesName === name) ?? false,
|
|
27
|
+
};
|
|
28
|
+
})
|
|
29
|
+
.filter((entry) => entry !== null);
|
|
30
|
+
}, [series, maxPoints, seriesNameFormatter, regressions]);
|
|
31
|
+
const { canvasRef, wrapperRef } = useChartLifecycle((theme) => {
|
|
32
|
+
if (entries.length === 0)
|
|
33
|
+
return null;
|
|
34
|
+
const resolvedLineWidth = lineWidth ?? (compact ? 1.5 : 1.75);
|
|
35
|
+
const datasets = entries.map((entry) => {
|
|
36
|
+
const lastIdx = entry.points.length - 1;
|
|
37
|
+
return {
|
|
38
|
+
label: entry.label,
|
|
39
|
+
data: entry.points.map((point) => ({ x: point.timestamp, y: point.value })),
|
|
40
|
+
borderColor: entry.color,
|
|
41
|
+
backgroundColor: `${entry.color}22`,
|
|
42
|
+
fill: entries.length === 1,
|
|
43
|
+
tension: 0,
|
|
44
|
+
borderWidth: resolvedLineWidth,
|
|
45
|
+
clip: 8,
|
|
46
|
+
spanGaps: true,
|
|
47
|
+
pointRadius: entry.points.map((_, index) => (entry.isRegressed && index === lastIdx ? (compact ? 4 : 5) : (compact ? 1.75 : 2.5))),
|
|
48
|
+
pointHoverRadius: compact ? 4 : 6,
|
|
49
|
+
pointBackgroundColor: entry.points.map((_, index) => (entry.isRegressed && index === lastIdx ? REGRESSION_COLOR : entry.color)),
|
|
50
|
+
pointBorderColor: entry.points.map((_, index) => (entry.isRegressed && index === lastIdx ? REGRESSION_BORDER_COLOR : entry.color)),
|
|
51
|
+
};
|
|
52
|
+
});
|
|
53
|
+
const options = {
|
|
54
|
+
...baseLineOptions(),
|
|
55
|
+
layout: { padding: layoutPadding(compact) },
|
|
56
|
+
interaction: { mode: "nearest", intersect: false },
|
|
57
|
+
plugins: {
|
|
58
|
+
legend: { display: false },
|
|
59
|
+
tooltip: {
|
|
60
|
+
...sharedTooltipStyle(theme),
|
|
61
|
+
callbacks: {
|
|
62
|
+
title: (items) => {
|
|
63
|
+
const ts = items[0]?.label;
|
|
64
|
+
return ts ? new Date(ts).toLocaleString() : "";
|
|
65
|
+
},
|
|
66
|
+
afterLabel: (item) => {
|
|
67
|
+
const seriesEntry = entries[item.datasetIndex];
|
|
68
|
+
if (!seriesEntry)
|
|
69
|
+
return "";
|
|
70
|
+
const pt = seriesEntry.points[item.dataIndex];
|
|
71
|
+
const parts = [];
|
|
72
|
+
if (pt?.commit)
|
|
73
|
+
parts.push(`commit: ${pt.commit.slice(0, 8)}`);
|
|
74
|
+
if (pt?.range != null)
|
|
75
|
+
parts.push(`± ${pt.range}`);
|
|
76
|
+
return parts.join("\n");
|
|
77
|
+
},
|
|
78
|
+
},
|
|
79
|
+
},
|
|
80
|
+
},
|
|
81
|
+
scales: {
|
|
82
|
+
x: timeXAxis(theme, { maxTicksLimit: compact ? 4 : 7 }),
|
|
83
|
+
y: yAxisConfig(theme, {
|
|
84
|
+
showTitle: !compact,
|
|
85
|
+
title: series.unit ?? series.metric,
|
|
86
|
+
maxTicksLimit: compact ? 4 : 6,
|
|
87
|
+
tickCallback: (value) => formatValue(Number(value), compact),
|
|
88
|
+
}),
|
|
89
|
+
},
|
|
90
|
+
};
|
|
91
|
+
return { type: "line", data: { datasets: datasets }, options };
|
|
92
|
+
}, [compact, entries, lineWidth, series.metric, series.unit]);
|
|
93
|
+
return (_jsxs("div", { ref: wrapperRef, class: ["bk-chart-panel", className].filter(Boolean).join(" "), children: [(title || subtitle) && (_jsxs("div", { class: "bk-chart-panel__header", children: [_jsxs("div", { children: [title && _jsx("h3", { class: "bk-chart-panel__title", children: title }), subtitle && _jsx("p", { class: "bk-chart-panel__subtitle", children: subtitle }), summary && _jsx("p", { class: "bk-chart-panel__summary", children: summary })] }), showSeriesCount && (_jsxs("span", { class: "bk-badge bk-badge--muted", children: [entries.length, " visible"] }))] })), showLegend && entries.length > 1 && (_jsx("div", { class: "bk-chart-legend", children: entries.map((entry) => (_jsxs("span", { class: "bk-chart-legend__item", title: entry.label, children: [_jsx("span", { class: "bk-chart-legend__swatch", style: { background: entry.color } }), _jsx("span", { class: "bk-chart-legend__label", children: entry.label })] }, entry.name))) })), _jsx("div", { class: "bk-chart-panel__canvas", style: { height: `${height}px` }, children: entries.length === 0 ? (_jsx("div", { class: "bk-chart-panel__empty", children: _jsxs("div", { children: [_jsx("strong", { children: "No series to display." }), _jsx("div", { children: "Try clearing filters or widening the selected metric." })] }) })) : (_jsxs("canvas", { ref: canvasRef, role: "img", "aria-label": title ?? `Trend chart for ${series.metric}`, children: ["Trend chart for ", title ?? series.metric] })) })] }));
|
|
94
|
+
}
|
|
95
|
+
//# sourceMappingURL=TrendChart.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TrendChart.js","sourceRoot":"","sources":["../../src/components/TrendChart.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { ComparisonResult } from "@benchkit/format";
|
|
2
|
+
export interface VerdictBannerProps {
|
|
3
|
+
result: ComparisonResult;
|
|
4
|
+
currentLabel?: string;
|
|
5
|
+
baselineLabel?: string;
|
|
6
|
+
/** Override the headline when regressions exist. Receives the count. */
|
|
7
|
+
regressionHeadline?: (count: number) => string;
|
|
8
|
+
/** Override the headline when no regressions exist. */
|
|
9
|
+
cleanHeadline?: string;
|
|
10
|
+
class?: string;
|
|
11
|
+
}
|
|
12
|
+
export declare function VerdictBanner({ result, currentLabel, baselineLabel, regressionHeadline, cleanHeadline, class: className, }: VerdictBannerProps): import("preact").JSX.Element;
|
|
13
|
+
//# sourceMappingURL=VerdictBanner.d.ts.map
|