Graph range vector selectors as instant vector selectors with notice

Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
Julius Volz 2024-09-08 21:11:06 +02:00
parent 1f1ca37fd7
commit d23872ef30
2 changed files with 59 additions and 26 deletions

View File

@ -1,5 +1,5 @@
import { FC, useEffect, useId, useState } from "react";
import { Alert, Skeleton, Box, LoadingOverlay } from "@mantine/core";
import { Alert, Skeleton, Box, LoadingOverlay, Stack } from "@mantine/core";
import { IconAlertTriangle, IconInfoCircle } from "@tabler/icons-react";
import { RangeQueryResult } from "../../api/responseTypes/query";
import { SuccessAPIResponse, useAPIQuery } from "../../api/api";
@ -13,9 +13,12 @@ import "uplot/dist/uPlot.min.css";
import "./uplot.css";
import { useElementSize } from "@mantine/hooks";
import UPlotChart, { UPlotChartRange } from "./UPlotChart";
import ASTNode, { nodeType } from "../../promql/ast";
import serializeNode from "../../promql/serialize";
export interface GraphProps {
expr: string;
node: ASTNode | null;
endTime: number | null;
range: number;
resolution: GraphResolution;
@ -27,6 +30,7 @@ export interface GraphProps {
const Graph: FC<GraphProps> = ({
expr,
node,
endTime,
range,
resolution,
@ -38,6 +42,22 @@ const Graph: FC<GraphProps> = ({
const { ref, width } = useElementSize();
const [rerender, setRerender] = useState(true);
const effectiveExpr =
node === null
? expr
: serializeNode(
node.type === nodeType.matrixSelector
? {
type: nodeType.vectorSelector,
name: node.name,
matchers: node.matchers,
offset: node.offset,
timestamp: node.timestamp,
startOrEnd: node.startOrEnd,
}
: node
);
const effectiveEndTime = (endTime !== null ? endTime : Date.now()) / 1000;
const startTime = effectiveEndTime - range / 1000;
const effectiveResolution = getEffectiveResolution(resolution, range) / 1000;
@ -47,12 +67,12 @@ const Graph: FC<GraphProps> = ({
key: [useId()],
path: "/query_range",
params: {
query: expr,
query: effectiveExpr,
step: effectiveResolution.toString(),
start: startTime.toString(),
end: effectiveEndTime.toString(),
},
enabled: expr !== "",
enabled: effectiveExpr !== "",
});
// Bundle the chart data and the displayed range together. This has two purposes:
@ -82,8 +102,8 @@ const Graph: FC<GraphProps> = ({
// Re-execute the query when the user presses Enter (or hits the Execute button).
useEffect(() => {
expr !== "" && refetch();
}, [retriggerIdx, refetch, expr, endTime, range, resolution]);
effectiveExpr !== "" && refetch();
}, [retriggerIdx, refetch, effectiveExpr, endTime, range, resolution]);
// The useElementSize hook above only gets a valid size on the second render, so this
// is a workaround to make the component render twice after mount.
@ -133,27 +153,39 @@ const Graph: FC<GraphProps> = ({
}
return (
<Box pos="relative" ref={ref} className={classes.chartWrapper}>
<LoadingOverlay
visible={isFetching}
zIndex={1000}
h={570}
overlayProps={{ radius: "sm", blur: 0.5 }}
loaderProps={{ type: "dots", color: "gray.6" }}
// loaderProps={{
// children: <Skeleton m={0} w="100%" h="100%" />,
// }}
// styles={{ loader: { width: "100%", height: "100%" } }}
/>
<UPlotChart
data={dataAndRange.data.data.result}
range={dataAndRange.range}
width={width}
showExemplars={showExemplars}
displayMode={displayMode}
onSelectRange={onSelectRange}
/>
</Box>
<Stack>
{node !== null && node.type === nodeType.matrixSelector && (
<Alert
color="orange"
title="Graphing modified expression"
icon={<IconAlertTriangle size={14} />}
>
<strong>Note:</strong> Range vector selectors can't be graphed, so
graphing the equivalent instant vector selector instead.
</Alert>
)}
<Box pos="relative" ref={ref} className={classes.chartWrapper}>
<LoadingOverlay
visible={isFetching}
zIndex={1000}
h={570}
overlayProps={{ radius: "sm", blur: 0.5 }}
loaderProps={{ type: "dots", color: "gray.6" }}
// loaderProps={{
// children: <Skeleton m={0} w="100%" h="100%" />,
// }}
// styles={{ loader: { width: "100%", height: "100%" } }}
/>
<UPlotChart
data={dataAndRange.data.data.result}
range={dataAndRange.range}
width={width}
showExemplars={showExemplars}
displayMode={displayMode}
onSelectRange={onSelectRange}
/>
</Box>
</Stack>
);
};

View File

@ -296,6 +296,7 @@ const QueryPanel: FC<PanelProps> = ({ idx, metricNames }) => {
<Space h="lg" />
<Graph
expr={expr}
node={selectedNode?.node ?? null}
endTime={panel.visualizer.endTime}
range={panel.visualizer.range}
resolution={panel.visualizer.resolution}