Implement timezone handling for uPlot graphs

Signed-off-by: Julius Volz <julius.volz@gmail.com>
This commit is contained in:
Julius Volz 2024-07-22 16:08:39 +02:00
parent 8ef66c41a0
commit 0049e8baff
2 changed files with 14 additions and 6 deletions

View file

@ -10,6 +10,7 @@ import "./uplot.css";
import { formatTimestamp } from "../../lib/formatTime"; import { formatTimestamp } from "../../lib/formatTime";
import { computePosition, shift, flip, offset } from "@floating-ui/dom"; import { computePosition, shift, flip, offset } from "@floating-ui/dom";
import { colorPool } from "./ColorPool"; import { colorPool } from "./ColorPool";
import { useSettings } from "../../state/settingsSlice";
const formatYAxisTickValue = (y: number | null): string => { const formatYAxisTickValue = (y: number | null): string => {
if (y === null) { if (y === null) {
@ -87,7 +88,7 @@ const formatLabels = (labels: { [key: string]: string }): string => `
.join("")} .join("")}
</div>`; </div>`;
const tooltipPlugin = () => { const tooltipPlugin = (useLocalTime: boolean) => {
let over: HTMLDivElement; let over: HTMLDivElement;
let boundingLeft: number; let boundingLeft: number;
let boundingTop: number; let boundingTop: number;
@ -162,7 +163,7 @@ const tooltipPlugin = () => {
// TODO: Use local time in formatTimestamp! // TODO: Use local time in formatTimestamp!
overlay.innerHTML = ` overlay.innerHTML = `
<div class="date">${formatTimestamp(ts, false)}</div> <div class="date">${formatTimestamp(ts, useLocalTime)}</div>
<div class="series-value"> <div class="series-value">
<span class="detail-swatch" style="background-color: ${color}"></span> <span class="detail-swatch" style="background-color: ${color}"></span>
<span>${labels.__name__ ? labels.__name__ + ": " : " "}<strong>${value}</strong></span> <span>${labels.__name__ ? labels.__name__ + ": " : " "}<strong>${value}</strong></span>
@ -235,6 +236,7 @@ const autoPadLeft = (
const getOptions = ( const getOptions = (
width: number, width: number,
result: RangeSamples[], result: RangeSamples[],
useLocalTime: boolean,
onSelectRange: (_start: number, _end: number) => void onSelectRange: (_start: number, _end: number) => void
): uPlot.Options => ({ ): uPlot.Options => ({
width: width - 30, width: width - 30,
@ -251,7 +253,10 @@ const getOptions = (
setScale: false, setScale: false,
}, },
}, },
plugins: [tooltipPlugin()], tzDate: useLocalTime
? undefined
: (ts) => uPlot.tzDate(new Date(ts * 1e3), "Etc/UTC"),
plugins: [tooltipPlugin(useLocalTime)],
legend: { legend: {
show: true, show: true,
live: false, live: false,
@ -391,14 +396,15 @@ const UPlotChart: FC<UPlotChartProps> = ({
onSelectRange, onSelectRange,
}) => { }) => {
const [options, setOptions] = useState<uPlot.Options | null>(null); const [options, setOptions] = useState<uPlot.Options | null>(null);
const { useLocalTime } = useSettings();
useEffect(() => { useEffect(() => {
if (width === 0) { if (width === 0) {
return; return;
} }
setOptions(getOptions(width, data, onSelectRange)); setOptions(getOptions(width, data, useLocalTime, onSelectRange));
}, [width, data, onSelectRange]); }, [width, data, useLocalTime, onSelectRange]);
const seriesData: uPlot.AlignedData = normalizeData( const seriesData: uPlot.AlignedData = normalizeData(
data, data,

View file

@ -21,6 +21,8 @@ export type GraphResolution =
value: number; // Resolution step in milliseconds. value: number; // Resolution step in milliseconds.
}; };
// From the UI settings, compute the effective resolution
// in milliseconds to use for the graph query.
export const getEffectiveResolution = ( export const getEffectiveResolution = (
resolution: GraphResolution, resolution: GraphResolution,
range: number range: number
@ -36,7 +38,7 @@ export const getEffectiveResolution = (
return Math.max(Math.floor(range / factor), 1); return Math.max(Math.floor(range / factor), 1);
} }
case "fixed": case "fixed":
return resolution.value; // TODO: Scope this to a list? return resolution.value;
case "custom": case "custom":
return resolution.value; return resolution.value;
} }