Skip to content

File tree

10 files changed

+394
-8
lines changed

10 files changed

+394
-8
lines changed

torchci/components/benchmark_v3/components/dataRender/auto/autoComponents.tsx

Lines changed: 74 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ import {
88
} from "lib/benchmark/api_helper/fe/hooks";
99
import { UIRenderConfig } from "lib/benchmark/store/benchmark_config_book";
1010
import { useDashboardSelector } from "lib/benchmark/store/benchmark_dashboard_provider";
11+
import BenchmarkRawDataTable from "../components/benchmarkTimeSeries/components/BenchmarkRawDataTable";
1112
import BenchmarkTimeSeriesChartGroup from "../components/benchmarkTimeSeries/components/BenchmarkTimeSeriesChart/BenchmarkTimeSeriesChartGroup";
1213
import { ComparisonTable } from "../components/benchmarkTimeSeries/components/BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTable";
1314

@@ -257,7 +258,6 @@ export function AutoBenchmarkPairwiseTable({ config }: AutoComponentProps) {
257258
}
258259

259260
if (!resp?.data?.data) {
260-
console.log("resp?.data?.data", resp, workflows);
261261
return <div>no data</div>;
262262
}
263263

@@ -358,3 +358,76 @@ export function AutoBenchmarkTimeSeriesChartGroup({
358358
</Grid>
359359
);
360360
}
361+
362+
export function AutoBenchmarkRawDataTable({ config }: AutoComponentProps) {
363+
const ctx = useBenchmarkCommittedContext();
364+
const ready =
365+
!!ctx &&
366+
!!ctx.committedTime?.start &&
367+
!!ctx.committedTime?.end &&
368+
!!ctx.committedLbranch &&
369+
!!ctx.committedRbranch &&
370+
ctx.requiredFilters.every((k: string) => !!ctx.committedFilters[k]);
371+
372+
const dataBinding = ctx?.configHandler.dataBinding;
373+
const uiRenderConfig = config as UIRenderConfig;
374+
375+
const branches = [
376+
...new Set(
377+
[ctx.committedLbranch, ctx.committedRbranch].filter((b) => b.length > 0)
378+
),
379+
];
380+
381+
// convert to the query params
382+
const params = dataBinding.toQueryParams({
383+
repo: ctx.repo,
384+
branches: branches,
385+
benchmarkName: ctx.benchmarkName,
386+
timeRange: ctx.committedTime,
387+
filters: ctx.committedFilters,
388+
maxSampling: ctx.committedMaxSampling,
389+
});
390+
391+
const queryParams: any | null = ready ? params : null;
392+
// fetch the bechmark data
393+
const {
394+
data: resp,
395+
isLoading,
396+
error,
397+
} = useBenchmarkTimeSeriesData(ctx.benchmarkId, queryParams, ["table"]);
398+
399+
if (isLoading) {
400+
return (
401+
<LoadingPage
402+
height={500}
403+
content="loading data for AutoBenchmarkRawDataTable..."
404+
/>
405+
);
406+
}
407+
408+
if (error) {
409+
return (
410+
<Alert severity="error">(AutoBenchmarkRawDataTable){error.message}</Alert>
411+
);
412+
}
413+
414+
if (!resp?.data?.data) {
415+
return <div>no data</div>;
416+
}
417+
const data = resp?.data?.data;
418+
419+
return (
420+
<Grid container sx={{ m: 1 }}>
421+
<Grid sx={{ p: 0.2 }} size={{ xs: 12 }}>
422+
<BenchmarkRawDataTable
423+
data={data["table"]}
424+
config={uiRenderConfig.config}
425+
title={{
426+
text: uiRenderConfig?.title ?? "Raw Table",
427+
description: "list all the workflow run data within the time range",
428+
}}
429+
/>
430+
</Grid>
431+
</Grid>
432+
);
433+
}
Lines changed: 261 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,261 @@
1+
import { Button, Typography } from "@mui/material";
2+
import { Box } from "@mui/system";
3+
import {
4+
DataGrid,
5+
GridColDef,
6+
GridRenderCellParams,
7+
useGridApiRef,
8+
} from "@mui/x-data-grid";
9+
import { RenderRawContent } from "components/benchmark_v3/components/common/RawContentDialog";
10+
import Link from "next/link";
11+
import { useMemo } from "react";
12+
import {
13+
fmtFixed2,
14+
formatHeaderName,
15+
getBenchmarkTimeSeriesComparisionTableRenderingConfig,
16+
renderBasedOnUnitConifg,
17+
} from "../helper";
18+
import { groupKeyAndLabel } from "./BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTableHelpers";
19+
20+
export default function BenchmarkRawDataTable({
21+
config,
22+
data,
23+
title,
24+
isDebug = false,
25+
}: {
26+
config: any;
27+
data: any;
28+
title?: {
29+
text: string;
30+
description?: string;
31+
};
32+
isDebug?: boolean;
33+
}) {
34+
const apiRef = useGridApiRef();
35+
36+
const rows: any[] = useMemo(() => {
37+
return ToRawTableRow(config, data);
38+
}, [data]);
39+
40+
const allColumns = useMemo(() => {
41+
const s = new Set<string>();
42+
rows.forEach((r) =>
43+
r.rowItem.forEach((i: any) => {
44+
Object.keys(i ?? {}).forEach((k) => {
45+
const groupItem = i[k];
46+
// helps debuging if the group item has more than one data item
47+
if (groupItem?.data?.length > 1) {
48+
groupItem.data.forEach((d: any, idx: number) => {
49+
s.add(`${k}||${idx}`);
50+
});
51+
} else {
52+
s.add(k);
53+
}
54+
});
55+
})
56+
);
57+
const auto = Array.from(s).sort();
58+
return auto;
59+
}, [rows]);
60+
61+
const columns: GridColDef[] = useMemo(
62+
() => getTableConlumnRendering(config, allColumns),
63+
[allColumns, config]
64+
);
65+
66+
return (
67+
<Box>
68+
<Typography variant="h6">{title?.text}</Typography>
69+
{title?.description && (
70+
<Typography variant="body2">{title.description}</Typography>
71+
)}
72+
{isDebug && (
73+
<RenderRawContent
74+
data={rows}
75+
title="Report Raw Json"
76+
buttonName="View Full Raw Data"
77+
type="json"
78+
/>
79+
)}
80+
<Button
81+
onClick={() =>
82+
apiRef?.current?.exportDataAsCsv({
83+
allColumns: true,
84+
utf8WithBom: true,
85+
fileName: "benchmark_raw_data",
86+
})
87+
}
88+
>
89+
Download CSV
90+
</Button>
91+
<DataGrid
92+
density="compact"
93+
apiRef={apiRef}
94+
rows={rows}
95+
columns={columns}
96+
pageSizeOptions={[25, 50, 100]}
97+
initialState={{
98+
sorting: {
99+
sortModel: [{ field: "timestamp", sort: "asc" }],
100+
},
101+
pagination: {
102+
paginationModel: { pageSize: 25 },
103+
},
104+
}}
105+
sx={{
106+
"& .MuiDataGrid-virtualScroller": { scrollbarGutter: "stable" },
107+
"& .MuiDataGrid-cell": {
108+
py: 0, // less vertical padding
109+
fontSize: "0.75rem",
110+
},
111+
"& .MuiDataGrid-columnHeaders": {
112+
minHeight: 32,
113+
lineHeight: "32px",
114+
fontSize: "0.75rem",
115+
},
116+
"& .MuiDataGrid-row": {
117+
minHeight: 32,
118+
},
119+
}}
120+
/>
121+
</Box>
122+
);
123+
}
124+
125+
/**
126+
* function to get the table column rendering logics
127+
*
128+
* @param config
129+
* @param metricFields
130+
* @returns
131+
*/
132+
function getTableConlumnRendering(
133+
config: any,
134+
metricFields: string[] = []
135+
): GridColDef[] {
136+
const metadataColumns: any[] = [
137+
{
138+
field: "workflow_run",
139+
headerName: "Workflow Run",
140+
minWidth: 140,
141+
valueGetter: (_value: any, row: any) => {
142+
const wf = row?.workflow_id ?? "";
143+
const job = row?.job_id ?? "";
144+
return `${wf}/${job}`;
145+
},
146+
valueFormatter: (value: any, row: any) => {
147+
return value ?? "";
148+
},
149+
renderCell: (params: GridRenderCellParams<any>) => (
150+
<Link href={params.row.job_url} target="_blank" rel="noopener">
151+
{params.value}
152+
</Link>
153+
),
154+
},
155+
{
156+
field: "commit",
157+
headerName: "Commit",
158+
renderCell: (params: GridRenderCellParams<any>) => (
159+
<Link href={params.row.commit_url} target="_blank" rel="noopener">
160+
<span
161+
style={{
162+
fontFamily: "ui-monospace, SFMono-Regular, Menlo, monospace",
163+
}}
164+
>
165+
{String(params.value).slice(0, 8)}
166+
</span>
167+
</Link>
168+
),
169+
},
170+
{
171+
field: "timestamp",
172+
headerName: "Timestamp",
173+
},
174+
];
175+
176+
const metadata = config?.extraMetadata ?? [];
177+
const metadataCols: GridColDef[] = metadata
178+
.filter((k: any) => !!k.field) // skip fields that are not defined
179+
.map((k: any) => ({
180+
field: k.field,
181+
headerName: k.displayName ?? k.field,
182+
flex: 0.5,
183+
renderCell: (p: any) => (
184+
<Typography variant="body2">{p.row[k.field]}</Typography>
185+
),
186+
}));
187+
188+
const metricCols: GridColDef[] = metricFields.map((field) => ({
189+
field,
190+
headerName: formatHeaderName(
191+
field,
192+
config?.renderOptions?.tableRenderingBook
193+
),
194+
sortable: false,
195+
filterable: false,
196+
valueGetter: (_value: any, row: any) => {
197+
const data = row.rowItem;
198+
if (data.length == 0) {
199+
return undefined;
200+
}
201+
let fieldName = field;
202+
let idx = 0;
203+
if (field.split("||").length > 1) {
204+
idx = Number(field.split("||")[1]);
205+
fieldName = field.split("||")[0];
206+
}
207+
const value = data[0][fieldName]?.data[idx]?.value;
208+
return value;
209+
},
210+
valueFormatter: (value: any, row: any) => {
211+
let fieldName = field;
212+
const rc = getBenchmarkTimeSeriesComparisionTableRenderingConfig(
213+
fieldName,
214+
config
215+
);
216+
return renderBasedOnUnitConifg(fmtFixed2(value), rc?.unit);
217+
},
218+
renderCell: (params: GridRenderCellParams<any>) => {
219+
return <Box>{params.formattedValue ?? ""}</Box>;
220+
},
221+
}));
222+
223+
return [...metadataColumns, ...metadataCols, ...metricCols];
224+
}
225+
226+
/**
227+
* Transform the data into a table row item
228+
* @param config
229+
* @param data
230+
* @returns
231+
*/
232+
export function ToRawTableRow(config: any, data: any) {
233+
const m = new Map<string, any>();
234+
for (const d of data ?? []) {
235+
const i = d.group_info;
236+
const wf = String(i?.workflow_id ?? "");
237+
const jobId = String(i?.job_id ?? "");
238+
const sourceRepo = i?.repo ?? "";
239+
const repoUrl = `https://github.com/${sourceRepo}`;
240+
const commitUrl = `${repoUrl}/commit/${i?.commit ?? ""}`;
241+
const jobUrl = `${repoUrl}/actions/runs/${wf}/job/${jobId}`;
242+
const rawData = d.data ?? [];
243+
const { key } = groupKeyAndLabel(i);
244+
if (!m.has(key)) {
245+
m.set(key, {
246+
...i,
247+
job_id: jobId,
248+
workflow_id: wf,
249+
commit: i?.commit ?? "",
250+
commit_url: commitUrl,
251+
job_url: jobUrl,
252+
repo: String(i?.repo ?? ""),
253+
timestamp: i?.granularity_bucket ?? "",
254+
id: key,
255+
rowItem: [],
256+
});
257+
}
258+
m.get(key)!.rowItem.push(rawData);
259+
}
260+
return Array.from(m.values());
261+
}

torchci/components/benchmark_v3/components/dataRender/components/benchmarkTimeSeries/components/BenchmarkTimeSeriesComparisonSection/BenchmarkTimeSeriesComparisonTable/ComparisonTable.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Typography } from "@mui/material";
2+
import { Box } from "@mui/system";
23
import {
34
DataGrid,
45
GridColDef,
@@ -87,7 +88,7 @@ export function ComparisonTable({
8788
);
8889

8990
return (
90-
<>
91+
<Box>
9192
<Typography variant="h6">{title.text}</Typography>
9293
{title.description && (
9394
<Typography variant="body2">{title.description}</Typography>
@@ -138,6 +139,6 @@ export function ComparisonTable({
138139
enabled={config.enableDialog ?? false}
139140
config={config.customizedConfirmDialog}
140141
/>
141-
</>
142+
</Box>
142143
);
143144
}

0 commit comments

Comments
 (0)