feat(charting): unify configurable time windows
This commit is contained in:
@@ -15,7 +15,11 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from "@/components/ui/select";
|
||||
import { DEFAULT_CHART_RANGES, type ChartRangeOption } from "./chartRanges";
|
||||
import {
|
||||
DEFAULT_CHART_RANGES,
|
||||
type ChartRangeOption,
|
||||
type ChartRangeValue,
|
||||
} from "./chartRanges";
|
||||
import {
|
||||
formatScaled,
|
||||
metricScaleInfo,
|
||||
@@ -72,11 +76,11 @@ interface LineSeriesChartProps {
|
||||
scale?: MetricScale;
|
||||
/** Available displayed time ranges. Defaults to the shared range choices. */
|
||||
rangeOptions?: readonly ChartRangeOption[];
|
||||
/** Initial uncontrolled range. Defaults to the largest available option. */
|
||||
defaultRangeSeconds?: number;
|
||||
/** Initial uncontrolled range. Defaults to the largest numeric option. */
|
||||
defaultRangeSeconds?: ChartRangeValue;
|
||||
/** Controlled range for consumers that refetch when the selection changes. */
|
||||
rangeSeconds?: number;
|
||||
onRangeChange?: (rangeSeconds: number) => void;
|
||||
rangeSeconds?: ChartRangeValue;
|
||||
onRangeChange?: (range: ChartRangeValue) => void;
|
||||
}
|
||||
|
||||
/** Shared range-aware line chart renderer for Prometheus and qBittorrent data. */
|
||||
@@ -91,8 +95,11 @@ export function LineSeriesChart({
|
||||
onRangeChange,
|
||||
}: LineSeriesChartProps) {
|
||||
const initialRange =
|
||||
defaultRangeSeconds ?? rangeOptions[rangeOptions.length - 1]?.value;
|
||||
const [localRangeSeconds, setLocalRangeSeconds] = useState(initialRange);
|
||||
defaultRangeSeconds ??
|
||||
[...rangeOptions].reverse().find((range) => typeof range.value === "number")
|
||||
?.value;
|
||||
const [localRangeSeconds, setLocalRangeSeconds] =
|
||||
useState<ChartRangeValue | undefined>(initialRange);
|
||||
const selectedRangeSeconds = rangeSeconds ?? localRangeSeconds;
|
||||
const latestTimestamp = series.reduce(
|
||||
(max, seriesItem) =>
|
||||
@@ -102,9 +109,10 @@ export function LineSeriesChart({
|
||||
),
|
||||
0,
|
||||
);
|
||||
const cutoff = selectedRangeSeconds
|
||||
? latestTimestamp - selectedRangeSeconds * 1000
|
||||
: null;
|
||||
const cutoff =
|
||||
typeof selectedRangeSeconds === "number"
|
||||
? latestTimestamp - selectedRangeSeconds * 1000
|
||||
: null;
|
||||
const visibleSeries =
|
||||
cutoff !== null && latestTimestamp > 0
|
||||
? series.map((seriesItem) => ({
|
||||
@@ -125,7 +133,7 @@ export function LineSeriesChart({
|
||||
formatScaled(value, scaleInfo, unit);
|
||||
|
||||
function handleRangeChange(value: string) {
|
||||
const nextRange = Number(value);
|
||||
const nextRange: ChartRangeValue = value === "all" ? "all" : Number(value);
|
||||
setLocalRangeSeconds(nextRange);
|
||||
onRangeChange?.(nextRange);
|
||||
}
|
||||
@@ -136,7 +144,9 @@ export function LineSeriesChart({
|
||||
<div className="flex justify-end">
|
||||
<Select
|
||||
value={
|
||||
selectedRangeSeconds ? String(selectedRangeSeconds) : undefined
|
||||
selectedRangeSeconds === undefined
|
||||
? undefined
|
||||
: String(selectedRangeSeconds)
|
||||
}
|
||||
onValueChange={handleRangeChange}
|
||||
>
|
||||
|
||||
Reference in New Issue
Block a user