fix(usage): improve responsive token trend axis

This commit is contained in:
lzt404 committed 2026-09-23 02:47:28 +08:00
1 parent 286f4bbe1b
commit 820ad4d2c4
4 files changed
+82 -8

No files matched your search

+23 -6
View File
@@ -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(() => {
+30 -1
View File
@@ -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];