@@ -14,6 +14,8 @@ function App() {
1414 const [ compareMode , setCompareMode ] = useState ( 'normal' ) ;
1515 const [ relativeBaseline , setRelativeBaseline ] = useState ( 0.002 ) ;
1616 const [ absoluteBaseline , setAbsoluteBaseline ] = useState ( 0.005 ) ;
17+ const [ showLoss , setShowLoss ] = useState ( true ) ;
18+ const [ showGradNorm , setShowGradNorm ] = useState ( false ) ;
1719
1820 const handleFilesUploaded = useCallback ( ( files ) => {
1921 setUploadedFiles ( prev => [ ...prev , ...files ] ) ;
@@ -36,8 +38,16 @@ function App() {
3638 < div className = "w-full px-3 py-3" >
3739 < Header />
3840
39- < div className = "grid grid-cols-1 xl:grid-cols-5 gap-3 mt-4" >
40- < div className = "xl:col-span-1 space-y-3" > { /* ...existing code...*/ }
41+ < main
42+ id = "main-content"
43+ className = "grid grid-cols-1 xl:grid-cols-5 gap-3 mt-4"
44+ role = "main"
45+ >
46+ < aside
47+ className = "xl:col-span-1 space-y-3"
48+ role = "complementary"
49+ aria-label = "控制面板"
50+ >
4151 < FileUpload onFilesUploaded = { handleFilesUploaded } />
4252
4353 < RegexControls
@@ -58,51 +68,136 @@ function App() {
5868 />
5969 ) }
6070
61- < div className = "bg-white rounded-lg shadow-md p-3" >
62- < h3 className = "text-base font-semibold text-gray-800 mb-2" > 显示选项</ h3 >
71+ < section className = "bg-white rounded-lg shadow-md p-3" aria-labelledby = "display-options-heading" >
72+ < h3
73+ id = "display-options-heading"
74+ className = "text-base font-semibold text-gray-800 mb-2"
75+ >
76+ 🎛️ 显示选项
77+ </ h3 >
6378 < div className = "space-y-3" >
64- < label className = "flex items-center" >
65- < input
66- type = "checkbox"
67- checked = { showDataPoints }
68- onChange = { ( e ) => setShowDataPoints ( e . target . checked ) }
69- className = "rounded border-gray-300 text-blue-600 focus:ring-blue-500"
70- />
71- < span className = "ml-2 text-xs text-gray-700" > 显示数据点</ span >
72- </ label >
73-
7479 < div >
75- < label className = "block text-xs font-medium text-gray-700 mb-1" >
76- 相对误差 Baseline
80+ < h4 className = "text-xs font-medium text-gray-700 mb-2" > 📊 图表显示</ h4 >
81+ < div className = "space-y-2" >
82+ < label className = "flex items-center cursor-pointer hover:bg-gray-50 p-1 rounded" >
83+ < input
84+ type = "checkbox"
85+ checked = { showLoss }
86+ onChange = { ( e ) => setShowLoss ( e . target . checked ) }
87+ className = "rounded border-gray-300 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
88+ aria-describedby = "show-loss-description"
89+ />
90+ < span className = "ml-2 text-xs text-gray-700" > 📉 显示 Loss 函数</ span >
91+ < span
92+ id = "show-loss-description"
93+ className = "sr-only"
94+ >
95+ 控制是否显示损失函数图表
96+ </ span >
97+ </ label >
98+
99+ < label className = "flex items-center cursor-pointer hover:bg-gray-50 p-1 rounded" >
100+ < input
101+ type = "checkbox"
102+ checked = { showGradNorm }
103+ onChange = { ( e ) => setShowGradNorm ( e . target . checked ) }
104+ className = "rounded border-gray-300 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
105+ aria-describedby = "show-gradnorm-description"
106+ />
107+ < span className = "ml-2 text-xs text-gray-700" > 📈 显示 Grad Norm</ span >
108+ < span
109+ id = "show-gradnorm-description"
110+ className = "sr-only"
111+ >
112+ 控制是否显示梯度范数图表
113+ </ span >
114+ </ label >
115+ </ div >
116+ </ div >
117+
118+ < div className = "border-t pt-3" >
119+ < h4 className = "text-xs font-medium text-gray-700 mb-2" > ⚙️ 图表选项</ h4 >
120+ < label className = "flex items-center cursor-pointer hover:bg-gray-50 p-1 rounded" >
121+ < input
122+ type = "checkbox"
123+ checked = { showDataPoints }
124+ onChange = { ( e ) => setShowDataPoints ( e . target . checked ) }
125+ className = "rounded border-gray-300 text-blue-600 focus:ring-2 focus:ring-blue-500 focus:ring-offset-2"
126+ aria-describedby = "show-data-points-description"
127+ />
128+ < span className = "ml-2 text-xs text-gray-700" > 🔵 显示数据点</ span >
129+ < span
130+ id = "show-data-points-description"
131+ className = "sr-only"
132+ >
133+ 控制是否在图表上显示原始数据点
134+ </ span >
77135 </ label >
78- < input
79- type = "number"
80- step = "0.001"
81- value = { relativeBaseline }
82- onChange = { ( e ) => setRelativeBaseline ( parseFloat ( e . target . value ) || 0 ) }
83- className = "w-full px-2 py-1 text-xs border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
84- placeholder = "0.002"
85- />
86136 </ div >
87137
88- < div >
89- < label className = "block text-xs font-medium text-gray-700 mb-1" >
90- 绝对误差 Baseline
91- </ label >
92- < input
93- type = "number"
94- step = "0.001"
95- value = { absoluteBaseline }
96- onChange = { ( e ) => setAbsoluteBaseline ( parseFloat ( e . target . value ) || 0 ) }
97- className = "w-full px-2 py-1 text-xs border border-gray-300 rounded-md focus:ring-blue-500 focus:border-blue-500"
98- placeholder = "0.005"
99- />
138+ < div className = "border-t pt-3" >
139+ < h4 className = "text-xs font-medium text-gray-700 mb-2" > 基准线设置</ h4 >
140+ < div className = "space-y-3" >
141+ < div >
142+ < label
143+ htmlFor = "relative-baseline"
144+ className = "block text-xs font-medium text-gray-700 mb-1"
145+ >
146+ 相对误差 Baseline
147+ </ label >
148+ < input
149+ id = "relative-baseline"
150+ type = "number"
151+ step = "0.001"
152+ value = { relativeBaseline }
153+ onChange = { ( e ) => setRelativeBaseline ( parseFloat ( e . target . value ) || 0 ) }
154+ className = "w-full px-2 py-1 text-xs border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 focus:outline-none"
155+ placeholder = "0.002"
156+ aria-describedby = "relative-baseline-description"
157+ />
158+ < span
159+ id = "relative-baseline-description"
160+ className = "sr-only"
161+ >
162+ 设置相对误差对比的基准线数值
163+ </ span >
164+ </ div >
165+
166+ < div >
167+ < label
168+ htmlFor = "absolute-baseline"
169+ className = "block text-xs font-medium text-gray-700 mb-1"
170+ >
171+ 绝对误差 Baseline
172+ </ label >
173+ < input
174+ id = "absolute-baseline"
175+ type = "number"
176+ step = "0.001"
177+ value = { absoluteBaseline }
178+ onChange = { ( e ) => setAbsoluteBaseline ( parseFloat ( e . target . value ) || 0 ) }
179+ className = "w-full px-2 py-1 text-xs border border-gray-300 rounded-md focus:ring-2 focus:ring-blue-500 focus:border-blue-500 focus:outline-none"
180+ placeholder = "0.005"
181+ aria-describedby = "absolute-baseline-description"
182+ />
183+ < span
184+ id = "absolute-baseline-description"
185+ className = "sr-only"
186+ >
187+ 设置绝对误差对比的基准线数值
188+ </ span >
189+ </ div >
190+ </ div >
100191 </ div >
101192 </ div >
102- </ div >
103- </ div >
193+ </ section >
194+ </ aside >
104195
105- < div className = "xl:col-span-4" >
196+ < section
197+ className = "xl:col-span-4"
198+ role = "region"
199+ aria-label = "图表显示区域"
200+ >
106201 < ChartContainer
107202 files = { uploadedFiles }
108203 lossRegex = { lossRegex }
@@ -111,9 +206,11 @@ function App() {
111206 compareMode = { compareMode }
112207 relativeBaseline = { relativeBaseline }
113208 absoluteBaseline = { absoluteBaseline }
209+ showLoss = { showLoss }
210+ showGradNorm = { showGradNorm }
114211 />
115- </ div >
116- </ div >
212+ </ section >
213+ </ main >
117214 </ div >
118215 </ div >
119216 ) ;
0 commit comments