fix(usage): improve responsive token trend axis
This commit is contained in:
1 parent
286f4bbe1b
commit
820ad4d2c4
4 files changed
+82
-8
No files matched your search
@@ -1,5 +1,5 @@
|
||||
import { useConfirmation } from '../components/ConfirmationDialog';
|
||||
import { useCallback, useEffect, useMemo, useRef, useState, type KeyboardEvent, type PointerEvent as ReactPointerEvent } from 'react';
|
||||
import { useCallback, useEffect, useLayoutEffect, useMemo, useRef, useState, type KeyboardEvent, type PointerEvent as ReactPointerEvent } from 'react';
|
||||
import { invoke } from '@tauri-apps/api/core';
|
||||
import { listen } from '@tauri-apps/api/event';
|
||||
import {
|
||||
@@ -1144,7 +1144,7 @@ function UsageTrend({
|
||||
const [hoveredRatio, setHoveredRatio] = useState<number | null>(null);
|
||||
const [hiddenModels, setHiddenModels] = useState<string[]>([]);
|
||||
const plotRef = useRef<HTMLDivElement>(null);
|
||||
const [plotWidth, setPlotWidth] = useState(800);
|
||||
const [plotWidth, setPlotWidth] = useState(0);
|
||||
|
||||
const series = useMemo(
|
||||
() => buildUsageTrendSeries(points, range),
|
||||
@@ -1164,12 +1164,29 @@ function UsageTrend({
|
||||
|
||||
const count = series.points.length;
|
||||
|
||||
useEffect(() => {
|
||||
useLayoutEffect(() => {
|
||||
const plot = plotRef.current;
|
||||
if (!plot) return;
|
||||
const observer = new ResizeObserver(([entry]) => setPlotWidth(entry.contentRect.width));
|
||||
observer.observe(plot);
|
||||
return () => observer.disconnect();
|
||||
let frame = 0;
|
||||
const updateWidth = (width: number) => {
|
||||
cancelAnimationFrame(frame);
|
||||
frame = requestAnimationFrame(() => {
|
||||
const next = Math.max(0, Math.round(width));
|
||||
setPlotWidth((current) => current === next ? current : next);
|
||||
});
|
||||
};
|
||||
const measure = () => updateWidth(plot.getBoundingClientRect().width);
|
||||
measure();
|
||||
const observer = typeof ResizeObserver === 'undefined'
|
||||
? null
|
||||
: new ResizeObserver(([entry]) => updateWidth(entry.contentRect.width));
|
||||
observer?.observe(plot);
|
||||
window.addEventListener('resize', measure);
|
||||
return () => {
|
||||
cancelAnimationFrame(frame);
|
||||
observer?.disconnect();
|
||||
window.removeEventListener('resize', measure);
|
||||
};
|
||||
}, [count > 0]);
|
||||
|
||||
useEffect(() => {
|
||||
|
||||
@@ -265,7 +265,36 @@ export function trendTimeAxisTicks(start: Date, end: Date, width: number, labelW
|
||||
if (span <= 0) return [start];
|
||||
// Choose a readable time interval from the selected duration and available space.
|
||||
const minStep = span * labelWidth / Math.max(labelWidth, width);
|
||||
const steps = [1 / 60, 5 / 60, 15 / 60, 0.5, 1, 2, 3, 6, 12, 24, 48, 72, 168, 336, 720, 2160, 4380, 8760];
|
||||
const steps = [
|
||||
1 / 60,
|
||||
2 / 60,
|
||||
5 / 60,
|
||||
10 / 60,
|
||||
15 / 60,
|
||||
20 / 60,
|
||||
0.5,
|
||||
0.75,
|
||||
1,
|
||||
2,
|
||||
3,
|
||||
4,
|
||||
6,
|
||||
8,
|
||||
12,
|
||||
24,
|
||||
48,
|
||||
72,
|
||||
96,
|
||||
168,
|
||||
336,
|
||||
720,
|
||||
1440,
|
||||
2160,
|
||||
2880,
|
||||
4380,
|
||||
8760,
|
||||
17520,
|
||||
];
|
||||
const step = steps.map((hours) => hours * HOUR_MS).find((value) => value >= minStep)
|
||||
?? niceCeiling(minStep / (8760 * HOUR_MS)) * 8760 * HOUR_MS;
|
||||
const ticks = [start];
|
||||
|
||||
Reference in new issue
Block a user