@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.
Files changed (219) hide show
  1. package/README.md +640 -0
  2. package/dist/ComparisonSummaryTable.test.d.ts +2 -0
  3. package/dist/ComparisonSummaryTable.test.d.ts.map +1 -0
  4. package/dist/ComparisonSummaryTable.test.js +53 -0
  5. package/dist/ComparisonSummaryTable.test.js.map +1 -0
  6. package/dist/Dashboard.d.ts +25 -0
  7. package/dist/Dashboard.d.ts.map +1 -0
  8. package/dist/Dashboard.js +87 -0
  9. package/dist/Dashboard.js.map +1 -0
  10. package/dist/Dashboard.test.d.ts +2 -0
  11. package/dist/Dashboard.test.d.ts.map +1 -0
  12. package/dist/Dashboard.test.js +49 -0
  13. package/dist/Dashboard.test.js.map +1 -0
  14. package/dist/RunDashboard.d.ts +20 -0
  15. package/dist/RunDashboard.d.ts.map +1 -0
  16. package/dist/RunDashboard.js +174 -0
  17. package/dist/RunDashboard.js.map +1 -0
  18. package/dist/RunDashboard.test.d.ts +2 -0
  19. package/dist/RunDashboard.test.d.ts.map +1 -0
  20. package/dist/RunDashboard.test.js +58 -0
  21. package/dist/RunDashboard.test.js.map +1 -0
  22. package/dist/RunDetail.d.ts +26 -0
  23. package/dist/RunDetail.d.ts.map +1 -0
  24. package/dist/RunDetail.js +100 -0
  25. package/dist/RunDetail.js.map +1 -0
  26. package/dist/RunDetail.test.d.ts +2 -0
  27. package/dist/RunDetail.test.d.ts.map +1 -0
  28. package/dist/RunDetail.test.js +168 -0
  29. package/dist/RunDetail.test.js.map +1 -0
  30. package/dist/RunSelector.test.d.ts +2 -0
  31. package/dist/RunSelector.test.d.ts.map +1 -0
  32. package/dist/RunSelector.test.js +45 -0
  33. package/dist/RunSelector.test.js.map +1 -0
  34. package/dist/SampleChart.test.d.ts +2 -0
  35. package/dist/SampleChart.test.d.ts.map +1 -0
  36. package/dist/SampleChart.test.js +48 -0
  37. package/dist/SampleChart.test.js.map +1 -0
  38. package/dist/TagFilter.test.d.ts +2 -0
  39. package/dist/TagFilter.test.d.ts.map +1 -0
  40. package/dist/TagFilter.test.js +106 -0
  41. package/dist/TagFilter.test.js.map +1 -0
  42. package/dist/VerdictBanner.test.d.ts +2 -0
  43. package/dist/VerdictBanner.test.d.ts.map +1 -0
  44. package/dist/VerdictBanner.test.js +56 -0
  45. package/dist/VerdictBanner.test.js.map +1 -0
  46. package/dist/chart-config.d.ts +100 -0
  47. package/dist/chart-config.d.ts.map +1 -0
  48. package/dist/chart-config.js +81 -0
  49. package/dist/chart-config.js.map +1 -0
  50. package/dist/colors.d.ts +11 -0
  51. package/dist/colors.d.ts.map +1 -0
  52. package/dist/colors.js +16 -0
  53. package/dist/colors.js.map +1 -0
  54. package/dist/comparison-transforms.d.ts +22 -0
  55. package/dist/comparison-transforms.d.ts.map +1 -0
  56. package/dist/comparison-transforms.js +20 -0
  57. package/dist/comparison-transforms.js.map +1 -0
  58. package/dist/comparison-transforms.test.d.ts +2 -0
  59. package/dist/comparison-transforms.test.d.ts.map +1 -0
  60. package/dist/comparison-transforms.test.js +75 -0
  61. package/dist/comparison-transforms.test.js.map +1 -0
  62. package/dist/components/ComparisonBar.d.ts +13 -0
  63. package/dist/components/ComparisonBar.d.ts.map +1 -0
  64. package/dist/components/ComparisonBar.js +94 -0
  65. package/dist/components/ComparisonBar.js.map +1 -0
  66. package/dist/components/ComparisonChart.d.ts +31 -0
  67. package/dist/components/ComparisonChart.d.ts.map +1 -0
  68. package/dist/components/ComparisonChart.js +118 -0
  69. package/dist/components/ComparisonChart.js.map +1 -0
  70. package/dist/components/ComparisonSummaryTable.d.ts +29 -0
  71. package/dist/components/ComparisonSummaryTable.d.ts.map +1 -0
  72. package/dist/components/ComparisonSummaryTable.js +41 -0
  73. package/dist/components/ComparisonSummaryTable.js.map +1 -0
  74. package/dist/components/DashboardToolbar.d.ts +21 -0
  75. package/dist/components/DashboardToolbar.d.ts.map +1 -0
  76. package/dist/components/DashboardToolbar.js +14 -0
  77. package/dist/components/DashboardToolbar.js.map +1 -0
  78. package/dist/components/DateRangeFilter.d.ts +19 -0
  79. package/dist/components/DateRangeFilter.d.ts.map +1 -0
  80. package/dist/components/DateRangeFilter.js +44 -0
  81. package/dist/components/DateRangeFilter.js.map +1 -0
  82. package/dist/components/HeroSection.d.ts +12 -0
  83. package/dist/components/HeroSection.d.ts.map +1 -0
  84. package/dist/components/HeroSection.js +6 -0
  85. package/dist/components/HeroSection.js.map +1 -0
  86. package/dist/components/Leaderboard.d.ts +9 -0
  87. package/dist/components/Leaderboard.d.ts.map +1 -0
  88. package/dist/components/Leaderboard.js +41 -0
  89. package/dist/components/Leaderboard.js.map +1 -0
  90. package/dist/components/MetricCard.d.ts +16 -0
  91. package/dist/components/MetricCard.d.ts.map +1 -0
  92. package/dist/components/MetricCard.js +25 -0
  93. package/dist/components/MetricCard.js.map +1 -0
  94. package/dist/components/MetricDetailView.d.ts +15 -0
  95. package/dist/components/MetricDetailView.d.ts.map +1 -0
  96. package/dist/components/MetricDetailView.js +11 -0
  97. package/dist/components/MetricDetailView.js.map +1 -0
  98. package/dist/components/MonitorSection.d.ts +21 -0
  99. package/dist/components/MonitorSection.d.ts.map +1 -0
  100. package/dist/components/MonitorSection.js +38 -0
  101. package/dist/components/MonitorSection.js.map +1 -0
  102. package/dist/components/OverviewGrid.d.ts +17 -0
  103. package/dist/components/OverviewGrid.d.ts.map +1 -0
  104. package/dist/components/OverviewGrid.js +15 -0
  105. package/dist/components/OverviewGrid.js.map +1 -0
  106. package/dist/components/RunSelector.d.ts +20 -0
  107. package/dist/components/RunSelector.d.ts.map +1 -0
  108. package/dist/components/RunSelector.js +53 -0
  109. package/dist/components/RunSelector.js.map +1 -0
  110. package/dist/components/RunTable.d.ts +13 -0
  111. package/dist/components/RunTable.d.ts.map +1 -0
  112. package/dist/components/RunTable.js +24 -0
  113. package/dist/components/RunTable.js.map +1 -0
  114. package/dist/components/SampleChart.d.ts +21 -0
  115. package/dist/components/SampleChart.d.ts.map +1 -0
  116. package/dist/components/SampleChart.js +77 -0
  117. package/dist/components/SampleChart.js.map +1 -0
  118. package/dist/components/TagFilter.d.ts +12 -0
  119. package/dist/components/TagFilter.d.ts.map +1 -0
  120. package/dist/components/TagFilter.js +59 -0
  121. package/dist/components/TagFilter.js.map +1 -0
  122. package/dist/components/TrendChart.d.ts +25 -0
  123. package/dist/components/TrendChart.d.ts.map +1 -0
  124. package/dist/components/TrendChart.js +95 -0
  125. package/dist/components/TrendChart.js.map +1 -0
  126. package/dist/components/VerdictBanner.d.ts +13 -0
  127. package/dist/components/VerdictBanner.d.ts.map +1 -0
  128. package/dist/components/VerdictBanner.js +22 -0
  129. package/dist/components/VerdictBanner.js.map +1 -0
  130. package/dist/dashboard-labels.d.ts +47 -0
  131. package/dist/dashboard-labels.d.ts.map +1 -0
  132. package/dist/dashboard-labels.js +44 -0
  133. package/dist/dashboard-labels.js.map +1 -0
  134. package/dist/dashboard-labels.test.d.ts +2 -0
  135. package/dist/dashboard-labels.test.d.ts.map +1 -0
  136. package/dist/dashboard-labels.test.js +34 -0
  137. package/dist/dashboard-labels.test.js.map +1 -0
  138. package/dist/dataset-transforms.d.ts +41 -0
  139. package/dist/dataset-transforms.d.ts.map +1 -0
  140. package/dist/dataset-transforms.js +132 -0
  141. package/dist/dataset-transforms.js.map +1 -0
  142. package/dist/dataset-transforms.test.d.ts +2 -0
  143. package/dist/dataset-transforms.test.d.ts.map +1 -0
  144. package/dist/dataset-transforms.test.js +208 -0
  145. package/dist/dataset-transforms.test.js.map +1 -0
  146. package/dist/date-range.test.d.ts +2 -0
  147. package/dist/date-range.test.d.ts.map +1 -0
  148. package/dist/date-range.test.js +116 -0
  149. package/dist/date-range.test.js.map +1 -0
  150. package/dist/embed.d.ts +45 -0
  151. package/dist/embed.d.ts.map +1 -0
  152. package/dist/embed.js +170 -0
  153. package/dist/embed.js.map +1 -0
  154. package/dist/embed.test.d.ts +2 -0
  155. package/dist/embed.test.d.ts.map +1 -0
  156. package/dist/embed.test.js +15 -0
  157. package/dist/embed.test.js.map +1 -0
  158. package/dist/fetch.d.ts +27 -0
  159. package/dist/fetch.d.ts.map +1 -0
  160. package/dist/fetch.js +73 -0
  161. package/dist/fetch.js.map +1 -0
  162. package/dist/fetch.test.d.ts +2 -0
  163. package/dist/fetch.test.d.ts.map +1 -0
  164. package/dist/fetch.test.js +75 -0
  165. package/dist/fetch.test.js.map +1 -0
  166. package/dist/format-utils.d.ts +48 -0
  167. package/dist/format-utils.d.ts.map +1 -0
  168. package/dist/format-utils.js +98 -0
  169. package/dist/format-utils.js.map +1 -0
  170. package/dist/format-utils.test.d.ts +2 -0
  171. package/dist/format-utils.test.d.ts.map +1 -0
  172. package/dist/format-utils.test.js +103 -0
  173. package/dist/format-utils.test.js.map +1 -0
  174. package/dist/hooks/useChartLifecycle.d.ts +20 -0
  175. package/dist/hooks/useChartLifecycle.d.ts.map +1 -0
  176. package/dist/hooks/useChartLifecycle.js +46 -0
  177. package/dist/hooks/useChartLifecycle.js.map +1 -0
  178. package/dist/index.d.ts +27 -0
  179. package/dist/index.d.ts.map +1 -0
  180. package/dist/index.js +36 -0
  181. package/dist/index.js.map +1 -0
  182. package/dist/index.test.d.ts +2 -0
  183. package/dist/index.test.d.ts.map +1 -0
  184. package/dist/index.test.js +10 -0
  185. package/dist/index.test.js.map +1 -0
  186. package/dist/labels.d.ts +5 -0
  187. package/dist/labels.d.ts.map +1 -0
  188. package/dist/labels.js +41 -0
  189. package/dist/labels.js.map +1 -0
  190. package/dist/labels.test.d.ts +2 -0
  191. package/dist/labels.test.d.ts.map +1 -0
  192. package/dist/labels.test.js +28 -0
  193. package/dist/labels.test.js.map +1 -0
  194. package/dist/leaderboard.d.ts +29 -0
  195. package/dist/leaderboard.d.ts.map +1 -0
  196. package/dist/leaderboard.js +40 -0
  197. package/dist/leaderboard.js.map +1 -0
  198. package/dist/leaderboard.test.d.ts +2 -0
  199. package/dist/leaderboard.test.d.ts.map +1 -0
  200. package/dist/leaderboard.test.js +105 -0
  201. package/dist/leaderboard.test.js.map +1 -0
  202. package/dist/sample-utils.d.ts +4 -0
  203. package/dist/sample-utils.d.ts.map +1 -0
  204. package/dist/sample-utils.js +12 -0
  205. package/dist/sample-utils.js.map +1 -0
  206. package/dist/style.css +912 -0
  207. package/dist/theme.d.ts +12 -0
  208. package/dist/theme.d.ts.map +1 -0
  209. package/dist/theme.js +17 -0
  210. package/dist/theme.js.map +1 -0
  211. package/dist/utils.d.ts +37 -0
  212. package/dist/utils.d.ts.map +1 -0
  213. package/dist/utils.js +63 -0
  214. package/dist/utils.js.map +1 -0
  215. package/dist/utils.test.d.ts +2 -0
  216. package/dist/utils.test.d.ts.map +1 -0
  217. package/dist/utils.test.js +196 -0
  218. package/dist/utils.test.js.map +1 -0
  219. 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":";AAEA,OAAO,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAY/C,MAAM,UAAU,QAAQ,CAAC,EAAE,KAAK,EAAE,OAAO,EAAE,WAAW,EAAE,UAAU,EAAE,KAAK,EAAE,SAAS,EAAE,MAAM,EAAiB;IAC3G,MAAM,IAAI,GAAG,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;IAEjE,OAAO,CACL,cAAK,KAAK,EAAE,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,YACjE,cAAK,KAAK,EAAC,wBAAwB,YACjC,iBAAO,KAAK,EAAC,UAAU,aACrB,kBAAS,KAAK,EAAC,YAAY,sCAAgC,EAC3D,0BACE,yBACE,aAAI,KAAK,EAAC,KAAK,YAAE,MAAM,EAAE,SAAS,IAAI,KAAK,GAAM,EACjD,aAAI,KAAK,EAAC,KAAK,YAAE,MAAM,EAAE,UAAU,IAAI,MAAM,GAAM,EACnD,aAAI,KAAK,EAAC,KAAK,YAAE,MAAM,EAAE,YAAY,IAAI,QAAQ,GAAM,EACvD,aAAI,KAAK,EAAC,KAAK,YAAE,MAAM,EAAE,SAAS,IAAI,KAAK,GAAM,EACjD,aAAI,KAAK,EAAC,KAAK,EAAC,KAAK,EAAC,mBAAmB,YAAE,MAAM,EAAE,gBAAgB,IAAI,YAAY,GAAM,EACzF,aAAI,KAAK,EAAC,KAAK,YAAE,MAAM,EAAE,aAAa,IAAI,SAAS,GAAM,IACtD,GACC,EACR,0BACG,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CACjB,cAEE,KAAK,EAAE,EAAE,MAAM,EAAE,WAAW,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,SAAS,EAAE,EACtD,OAAO,EAAE,GAAG,EAAE,CAAC,WAAW,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,aAEpC,uBACE,eAAM,KAAK,EAAC,SAAS,YAAE,GAAG,CAAC,EAAE,GAAQ,GAClC,EACL,uBAAK,UAAU,CAAC,GAAG,CAAC,SAAS,CAAC,GAAM,EACpC,uBACG,GAAG,CAAC,MAAM,CAAC,CAAC,CAAC,CACZ,CAAC,GAAG,EAAE;wCACJ,MAAM,IAAI,GAAG,UAAU,EAAE,CAAC,GAAG,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;wCAC3C,MAAM,IAAI,GAAG,eAAM,KAAK,EAAC,SAAS,YAAE,GAAG,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,GAAQ,CAAC;wCACnE,OAAO,IAAI,CAAC,CAAC,CAAC,YAAG,IAAI,EAAE,IAAI,EAAE,MAAM,EAAC,QAAQ,EAAC,GAAG,EAAC,qBAAqB,YAAE,IAAI,GAAK,CAAC,CAAC,CAAC,IAAI,CAAC;oCAC3F,CAAC,CAAC,EAAE,CACL,CAAC,CAAC,CAAC,CACF,eAAM,KAAK,EAAC,UAAU,uBAAS,CAChC,GACE,EACL,uBAAK,SAAS,CAAC,GAAG,CAAC,GAAG,CAAC,GAAM,EAC7B,aAAI,KAAK,EAAC,mBAAmB,YAAE,GAAG,CAAC,UAAU,IAAI,GAAG,GAAM,EAC1D,aAAI,KAAK,EAAC,UAAU,YAAE,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,IAAI,CAAC,IAAI,GAAG,GAAM,KArBrD,GAAG,CAAC,EAAE,CAsBR,CACN,CAAC,GACI,EACP,OAAO,IAAI,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,OAAO,IAAI,CACzC,0BACE,uBACE,cAAI,OAAO,EAAE,CAAC,EAAE,KAAK,EAAC,UAAU,yBACrB,OAAO,UAAM,KAAK,CAAC,IAAI,CAAC,MAAM,aACpC,GACF,GACC,CACT,IACK,GACJ,GACF,CACP,CAAC;AACJ,CAAC;AAED,SAAS,UAAU,CAAC,EAAU;IAC5B,IAAI,CAAC;QACH,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAC,cAAc,CAAC,SAAS,EAAE;YAC5C,KAAK,EAAE,OAAO;YACd,GAAG,EAAE,SAAS;YACd,IAAI,EAAE,SAAS;YACf,MAAM,EAAE,SAAS;SAClB,CAAC,CAAC;IACL,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC"}
@@ -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":";AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,cAAc,CAAC;AACvC,OAAO,EAAE,WAAW,EAAE,MAAM,oBAAoB,CAAC;AACjD,OAAO,EACL,kBAAkB,EAClB,aAAa,EACb,eAAe,EACf,WAAW,EACX,WAAW,GACZ,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,KAAK,EACL,cAAc,EACd,WAAW,EACX,YAAY,EACZ,WAAW,EACX,OAAO,EACP,MAAM,GAGP,MAAM,UAAU,CAAC;AAElB,OAAO,EAAE,MAAM,EAAE,MAAM,cAAc,CAAC;AACtC,OAAO,EAAE,iBAAiB,EAAE,MAAM,+BAA+B,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAE1D,KAAK,CAAC,QAAQ,CAAC,cAAc,EAAE,WAAW,EAAE,YAAY,EAAE,WAAW,EAAE,OAAO,EAAE,MAAM,CAAC,CAAC;AAqBxF,MAAM,UAAU,WAAW,CAAC,EAC1B,OAAO,EACP,OAAO,EACP,MAAM,GAAG,GAAG,EACZ,KAAK,EACL,QAAQ,EACR,OAAO,GAAG,KAAK,EACf,SAAS,EACT,oBAAoB,EACpB,UAAU,GAAG,IAAI,EACjB,KAAK,EAAE,SAAS,GACC;IACjB,MAAM,eAAe,GAAG,OAAO,CAAC,GAAG,EAAE;QACnC,IAAI,OAAO,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC;YAAE,OAAO,OAAO,CAAC;QAClD,OAAO,oBAAoB,CAAC,OAAO,CAAC,CAAC;IACvC,CAAC,EAAE,CAAC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC;IAEvB,MAAM,QAAQ,GAAG,OAAO,CAAgC,GAAG,EAAE;QAC3D,OAAO,eAAe,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;YACzC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;YAC1C,MAAM,KAAK,GAAG,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;YAC3E,OAAO;gBACL,KAAK;gBACL,IAAI,EAAE,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC,IAAI,IAAI,EAAE,CAAC,CAAC;gBAC5D,WAAW,EAAE,KAAK;gBAClB,eAAe,EAAE,GAAG,KAAK,IAAI;gBAC7B,IAAI,EAAE,eAAe,CAAC,MAAM,KAAK,CAAC;gBAClC,OAAO,EAAE,CAAC;gBACV,WAAW,EAAE,SAAS,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC;gBAChD,IAAI,EAAE,CAAC;gBACP,QAAQ,EAAE,IAAI;gBACd,WAAW,EAAE,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG;gBACjC,gBAAgB,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;gBACjC,oBAAoB,EAAE,KAAK;gBAC3B,gBAAgB,EAAE,KAAK;aACxB,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC,EAAE,CAAC,eAAe,EAAE,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,SAAS,CAAC,CAAC,CAAC;IAEzE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,iBAAiB,CACjD,CAAC,KAAK,EAAE,EAAE;QACR,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,IAAI,CAAC;QAE/D,MAAM,OAAO,GAAyB;YACpC,GAAG,eAAe,EAAE;YACpB,MAAM,EAAE,EAAE,OAAO,EAAE,aAAa,CAAC,OAAO,CAAC,EAAE;YAC3C,WAAW,EAAE,EAAE,IAAI,EAAE,SAAS,EAAE,SAAS,EAAE,KAAK,EAAE;YAClD,OAAO,EAAE;gBACP,MAAM,EAAE,EAAE,OAAO,EAAE,KAAK,EAAE;gBAC1B,OAAO,EAAE;oBACP,GAAG,kBAAkB,CAAC,KAAK,CAAC;oBAC5B,SAAS,EAAE;wBACT,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,OAAO,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,IAAI,EAAE,GAAG;qBAClD;iBACF;aACF;YACD,MAAM,EAAE;gBACN,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE;oBACpB,KAAK,EAAE,kBAAkB;oBACzB,SAAS,EAAE,CAAC,OAAO;oBACnB,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC9B,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,GAAG,KAAK,GAAG;iBACrC,CAAC;gBACF,CAAC,EAAE,WAAW,CAAC,KAAK,EAAE;oBACpB,SAAS,EAAE,CAAC,OAAO,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC;oBACnD,KAAK,EAAE,eAAe,CAAC,CAAC,CAAC,IAAI,EAAE;oBAC/B,aAAa,EAAE,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;oBAC9B,YAAY,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,WAAW,CAAC,MAAM,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;iBAC7D,CAAC;aACH;SACF,CAAC;QAEF,OAAO,EAAE,IAAI,EAAE,MAAe,EAAE,IAAI,EAAE,EAAE,QAAQ,EAAE,EAAE,OAAO,EAAE,CAAC;IAChE,CAAC,EACD,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,MAAM,EAAE,eAAe,CAAC,CACrD,CAAC;IAEF,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,KAAK,CAAC,IAAI,eAAe,CAAC,MAAM,KAAK,CAAC,CAAC;IAErE,OAAO,CACL,eAAK,GAAG,EAAE,UAAU,EAAE,KAAK,EAAE,CAAC,gBAAgB,EAAE,SAAS,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,aACjF,CAAC,KAAK,IAAI,QAAQ,CAAC,IAAI,CACtB,cAAK,KAAK,EAAC,wBAAwB,YACjC,0BACG,KAAK,IAAI,aAAI,KAAK,EAAC,uBAAuB,YAAE,KAAK,GAAM,EACvD,QAAQ,IAAI,YAAG,KAAK,EAAC,0BAA0B,YAAE,QAAQ,GAAK,IAC3D,GACF,CACP,EAEA,UAAU,IAAI,CAAC,OAAO,IAAI,eAAe,CAAC,MAAM,GAAG,CAAC,IAAI,CACvD,cAAK,KAAK,EAAC,iBAAiB,YACzB,eAAe,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE;oBACnC,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;oBAC1C,MAAM,KAAK,GAAG,oBAAoB,CAAC,CAAC,CAAC,oBAAoB,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC;oBAC3E,OAAO,CACL,gBAAmB,KAAK,EAAC,uBAAuB,EAAC,KAAK,EAAE,KAAK,aAC3D,eAAM,KAAK,EAAC,yBAAyB,EAAC,KAAK,EAAE,EAAE,UAAU,EAAE,KAAK,EAAE,GAAI,EACtE,eAAM,KAAK,EAAC,wBAAwB,YAAE,KAAK,GAAQ,KAF1C,MAAM,CAGV,CACR,CAAC;gBACJ,CAAC,CAAC,GACE,CACP,EAED,cAAK,KAAK,EAAC,wBAAwB,EAAC,KAAK,EAAE,EAAE,MAAM,EAAE,GAAG,MAAM,IAAI,EAAE,YACjE,OAAO,CAAC,CAAC,CAAC,CACT,cAAK,KAAK,EAAC,uBAAuB,YAChC,0BACE,+CAAgC,EAChC,+FAA6E,IACzE,GACF,CACP,CAAC,CAAC,CAAC,CACF,iBACE,GAAG,EAAE,SAAS,EACd,IAAI,EAAC,KAAK,gBACE,KAAK,IAAI,cAAc,YAElC,KAAK,IAAI,cAAc,GACjB,CACV,GACG,IACF,CACP,CAAC;AACJ,CAAC"}
@@ -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