Skip to content

Commit a204e04

Browse files
authored
Merge pull request #14 from JavaZeroo/codex/improve-left-toolbar-and-add-hide-button
Add sidebar toggle
2 parents 8b0f15b + 0534e2a commit a204e04

File tree

2 files changed

+95
-28
lines changed

2 files changed

+95
-28
lines changed

src/App.jsx

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import ChartContainer from './components/ChartContainer';
66
import { ComparisonControls } from './components/ComparisonControls';
77
import { Header } from './components/Header';
88
import { FileConfigModal } from './components/FileConfigModal';
9+
import { PanelLeftClose, PanelLeftOpen } from 'lucide-react';
910

1011
function App() {
1112
const [uploadedFiles, setUploadedFiles] = useState([]);
@@ -37,6 +38,7 @@ function App() {
3738
const [, setDragCounter] = useState(0);
3839
const [xRange, setXRange] = useState({ min: undefined, max: undefined });
3940
const [maxStep, setMaxStep] = useState(0);
41+
const [sidebarVisible, setSidebarVisible] = useState(true);
4042

4143
const handleFilesUploaded = useCallback((files) => {
4244
const filesWithDefaults = files.map(file => ({
@@ -188,7 +190,7 @@ function App() {
188190
<div className="min-h-screen bg-gradient-to-br from-blue-50 to-indigo-100 relative">
189191
{/* 全页面拖拽覆盖层 */}
190192
{globalDragOver && (
191-
<div
193+
<div
192194
className="fixed inset-0 bg-blue-600 bg-opacity-95 z-50 flex items-center justify-center backdrop-blur-sm drag-overlay-fade-in"
193195
>
194196
<div
@@ -230,20 +232,31 @@ function App() {
230232
</div>
231233
)}
232234

235+
{!sidebarVisible && (
236+
<button
237+
onClick={() => setSidebarVisible(true)}
238+
className="fixed top-3 left-3 z-40 p-2 bg-white rounded-full shadow-md text-gray-600 hover:text-gray-800 focus:outline-none focus:ring-2 focus:ring-blue-500"
239+
aria-label="显示工具栏"
240+
>
241+
<PanelLeftOpen size={20} aria-hidden="true" />
242+
</button>
243+
)}
244+
233245
<div className="w-full px-3 py-3">
234-
235-
<main
246+
247+
<main
236248
id="main-content"
237-
className="grid grid-cols-1 xl:grid-cols-5 gap-3"
249+
className="grid grid-cols-1 xl:grid-cols-5 gap-3"
238250
role="main"
239251
>
240-
<aside
241-
className="xl:col-span-1 space-y-3"
242-
role="complementary"
243-
aria-label="控制面板"
244-
>
245-
{/* 标题信息 */}
246-
<div className="bg-white rounded-lg shadow-md p-3">
252+
{sidebarVisible && (
253+
<aside
254+
className="xl:col-span-1 space-y-3"
255+
role="complementary"
256+
aria-label="控制面板"
257+
>
258+
{/* 标题信息 */}
259+
<div className="bg-white rounded-lg shadow-md p-3">
247260
<div className="flex items-center gap-2 mb-2">
248261
<div className="p-2 bg-blue-100 rounded-lg">
249262
<svg className="w-5 h-5 text-blue-600" fill="none" viewBox="0 0 24 24" stroke="currentColor">
@@ -253,6 +266,13 @@ function App() {
253266
<h1 className="text-lg font-bold text-gray-800">
254267
Log Analyzer
255268
</h1>
269+
<button
270+
onClick={() => setSidebarVisible(false)}
271+
className="ml-auto p-1 text-gray-400 hover:text-gray-600 focus:outline-none focus:ring-2 focus:ring-blue-500 rounded"
272+
aria-label="隐藏工具栏"
273+
>
274+
<PanelLeftClose size={16} aria-hidden="true" />
275+
</button>
256276
</div>
257277
<p className="text-sm text-gray-600 mb-3">
258278
📊 分析和可视化大模型训练日志中的损失函数和梯度范数数据
@@ -375,11 +395,12 @@ function App() {
375395
</div>
376396
</div>
377397
</div>
378-
</section>
379-
</aside>
398+
</section>
399+
</aside>
400+
)}
380401

381-
<section
382-
className="xl:col-span-4"
402+
<section
403+
className={sidebarVisible ? 'xl:col-span-4' : 'xl:col-span-5'}
383404
role="region"
384405
aria-label="图表显示区域"
385406
>

src/components/ChartContainer.jsx

Lines changed: 59 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,30 @@ export default function ChartContainer({
214214
return result;
215215
};
216216

217+
const calculateYRange = useCallback((dataArray) => {
218+
let min = Infinity;
219+
let max = -Infinity;
220+
dataArray.forEach(item => {
221+
item.data.forEach(point => {
222+
const inRange =
223+
(xRange.min === undefined || point.x >= xRange.min) &&
224+
(xRange.max === undefined || point.x <= xRange.max);
225+
if (inRange) {
226+
if (point.y < min) min = point.y;
227+
if (point.y > max) max = point.y;
228+
}
229+
});
230+
});
231+
if (min === Infinity || max === -Infinity) {
232+
return { min: 0, max: 1 };
233+
}
234+
if (min === max) {
235+
return { min: min - 1, max: max + 1 };
236+
}
237+
const pad = (max - min) * 0.05;
238+
return { min: min - pad, max: max + pad };
239+
}, [xRange]);
240+
217241
const chartOptions = useMemo(() => ({
218242
responsive: true,
219243
maintainAspectRatio: false,
@@ -326,7 +350,6 @@ export default function ChartContainer({
326350
display: true,
327351
title: { display: true, text: 'Value' },
328352
bounds: 'data',
329-
grace: '20%',
330353
ticks: {
331354
callback: function (value) {
332355
return Number(value.toPrecision(2));
@@ -429,6 +452,15 @@ export default function ChartContainer({
429452
const dataArray = metricDataArrays[key] || [];
430453
const showComparison = dataArray.length === 2;
431454

455+
const yRange = calculateYRange(dataArray);
456+
const options = {
457+
...chartOptions,
458+
scales: {
459+
...chartOptions.scales,
460+
y: { ...chartOptions.scales.y, min: yRange.min, max: yRange.max }
461+
}
462+
};
463+
432464
let stats = null;
433465
if (showComparison) {
434466
const normalDiff = getComparisonData(dataArray[0].data, dataArray[1].data, 'normal');
@@ -442,6 +474,30 @@ export default function ChartContainer({
442474
};
443475
}
444476

477+
let comparisonChart = null;
478+
if (showComparison) {
479+
const compData = createComparisonChartData(dataArray[0], dataArray[1], key);
480+
const compRange = calculateYRange(compData.datasets);
481+
const compOptions = {
482+
...chartOptions,
483+
scales: {
484+
...chartOptions.scales,
485+
y: { ...chartOptions.scales.y, min: compRange.min, max: compRange.max }
486+
}
487+
};
488+
comparisonChart = (
489+
<ResizablePanel title={`⚖️ ${key} 对比分析 (${compareMode})`} initialHeight={440}>
490+
<ChartWrapper
491+
chartId={`metric-comp-${idx}`}
492+
onRegisterChart={registerChart}
493+
onSyncHover={syncHoverToAllCharts}
494+
data={compData}
495+
options={compOptions}
496+
/>
497+
</ResizablePanel>
498+
);
499+
}
500+
445501
return (
446502
<div key={key} className="flex flex-col gap-3">
447503
<ResizablePanel title={key} initialHeight={440}>
@@ -450,20 +506,10 @@ export default function ChartContainer({
450506
onRegisterChart={registerChart}
451507
onSyncHover={syncHoverToAllCharts}
452508
data={createChartData(dataArray)}
453-
options={chartOptions}
509+
options={options}
454510
/>
455511
</ResizablePanel>
456-
{showComparison && (
457-
<ResizablePanel title={`⚖️ ${key} 对比分析 (${compareMode})`} initialHeight={440}>
458-
<ChartWrapper
459-
chartId={`metric-comp-${idx}`}
460-
onRegisterChart={registerChart}
461-
onSyncHover={syncHoverToAllCharts}
462-
data={createComparisonChartData(dataArray[0], dataArray[1], key)}
463-
options={chartOptions}
464-
/>
465-
</ResizablePanel>
466-
)}
512+
{comparisonChart}
467513
{stats && (
468514
<div className="bg-white rounded-lg shadow-md p-3">
469515
<h4 className="text-sm font-medium text-gray-700 mb-1">{key} 差值统计</h4>

0 commit comments

Comments
 (0)