Graph range vector selectors as instant vector selectors with notice
Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
parent
1f1ca37fd7
commit
d23872ef30
|
@ -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>
|
||||
);
|
||||
};
|
||||
|
||||
|
|
|
@ -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}
|
||||
|
|
Loading…
Reference in New Issue