Skip to content

Commit

Permalink
Support selection of multiple metrics
Browse files Browse the repository at this point in the history
Modify the metrics pulldown to allow multiple selection. The statistical
summary chart and graph will show all selected metrics in addition to the
inherent benchmark primary benchmark (for the primary period).
  • Loading branch information
dbutenhof committed Nov 7, 2024
1 parent f2c28fd commit ea19d5a
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 37 deletions.
45 changes: 28 additions & 17 deletions frontend/src/actions/ilabActions.js
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,7 @@ export const fetchMetricsInfo = (uid) => async (dispatch) => {
) {
dispatch({
type: TYPES.SET_ILAB_METRICS,
payload: { uid, metrics: Object.keys(response.data) },
payload: { uid, metrics: Object.keys(response.data).sort() },
});
}
}
Expand Down Expand Up @@ -137,13 +137,15 @@ export const fetchSummaryData =
periods: [p.id],
});
}
if (metric) {
summaries.push({
run: uid,
metric,
aggregate: true,
periods: [p.id],
});
if (metrics) {
metrics.forEach((metric) =>
summaries.push({
run: uid,
metric,
aggregate: true,
periods: [p.id],
})
);
}
});
const response = await API.post(
Expand Down Expand Up @@ -202,6 +204,7 @@ export const fetchGraphData =
const periods = getState().ilab.periods.find((i) => i.uid == uid);
const graphData = cloneDeep(getState().ilab.graphData);
const filterData = graphData.filter((i) => i.uid !== uid);
const metrics = getState().ilab.metrics_selected[uid];
dispatch({
type: TYPES.SET_ILAB_GRAPH_DATA,
payload: filterData,
Expand All @@ -213,13 +216,15 @@ export const fetchGraphData =
if (p.is_primary) {
graphs.push({ run: uid, metric: p.primary_metric, periods: [p.id] });
}
if (metric) {
graphs.push({
run: uid,
metric,
aggregate: true,
periods: [p.id],
});
if (metrics) {
metrics.forEach((metric) =>
graphs.push({
run: uid,
metric,
aggregate: true,
periods: [p.id],
})
);
}
});
const response = await API.post(`/api/v1/ilab/runs/multigraph`, {
Expand Down Expand Up @@ -369,9 +374,15 @@ export const checkIlabJobs = (newPage) => (dispatch, getState) => {
}
};

export const setSelectedMetrics = (id, metrics) => (dispatch, getState) => {
export const toggleSelectedMetric = (id, metric) => (dispatch, getState) => {
const metrics_selected = cloneDeep(getState().ilab.metrics_selected);
metrics_selected[id] = metrics;
var new_selected = metrics_selected[id] ? metrics_selected[id] : [];
if (new_selected.includes(metric)) {
new_selected = new_selected.filter((m) => m !== metric);
} else {
new_selected = [...new_selected, metric];
}
metrics_selected[id] = new_selected;
dispatch({
type: TYPES.SET_ILAB_SELECTED_METRICS,
payload: metrics_selected,
Expand Down
45 changes: 25 additions & 20 deletions frontend/src/components/templates/ILab/MetricsDropdown.jsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import {
Badge,
MenuToggle,
Select,
SelectList,
SelectOption,
Skeleton
Skeleton,
} from "@patternfly/react-core";
import { fetchGraphData, fetchSummaryData, setSelectedMetrics } from "@/actions/ilabActions";
import {
fetchGraphData,
fetchSummaryData,
toggleSelectedMetric,
} from "@/actions/ilabActions";
import { useDispatch, useSelector } from "react-redux";

import PropTypes from "prop-types";
Expand All @@ -16,34 +21,33 @@ import { useState } from "react";
const MetricsSelect = (props) => {
const { metrics, metrics_selected } = useSelector((state) => state.ilab);
const { item } = props;
var current_metrics = metrics_selected[item.id]
? metrics_selected[item.id]
: [];

/* Metrics select */
const [isOpen, setIsOpen] = useState(false);
const dispatch = useDispatch();
// const [selected, setSelected] = useState("Select a value");

const toggle1 = (toggleRef, selected) => (
const toggle1 = (toggleRef) => (
<MenuToggle
ref={toggleRef}
onClick={onToggleClick}
isExpanded={isOpen}
style={{
width: "200px",
}}
badge={<Badge isRead>{`${current_metrics.length} selected`}</Badge>}
>
{selected}
Additional metrics
</MenuToggle>
);

const onToggleClick = () => {
setIsOpen(!isOpen);
};
const onSelect = (_event, value) => {
console.log("selected", value);
const [run, metric] = value;
dispatch(setSelectedMetrics(run, metric));
dispatch(toggleSelectedMetric(run, metric));
dispatch(fetchGraphData(run, metric));
dispatch(fetchSummaryData(run, metric));
setIsOpen(false);
};
const metricsDataCopy = cloneDeep(metrics);

Expand All @@ -53,36 +57,37 @@ const MetricsSelect = (props) => {
};
const hasMetricsData = (uuid) => {
const hasData = getMetricsData(uuid).length > 0;

return hasData;
};
/* Metrics select */
return (
<>
{hasMetricsData(item.id) ? (
<Select
id="single-select"
id="checkbox-select"
role="menu"
isOpen={isOpen}
selected={metrics_selected[item.id]}
selected={current_metrics}
onSelect={onSelect}
onOpenChange={(isOpen) => setIsOpen(isOpen)}
toggle={(ref) => toggle1(ref, metrics_selected[item.id])}
shouldFocusToggleOnSelect
toggle={toggle1}
>
<SelectList>
{getMetricsData(item.id)[0]?.metrics.map((metric) => (
<SelectOption
key={uid()}
key={metric}
isSelected={current_metrics.includes(metric)}
hasCheckbox
value={[item.id, metric]}
>
{metric}
</SelectOption>
))}
</SelectList>
</Select>
):
<Skeleton width="33%" screenreaderText="Loaded 33% of content" />
}
) : (
<Skeleton width="33%" screenreaderText="Loaded 33% of content" />
)}
</>
);
};
Expand Down

0 comments on commit ea19d5a

Please sign in to comment.