1- import React , { useMemo , useState , useRef , useCallback , useEffect } from 'react' ;
1+ import React , { useMemo , useRef , useCallback , useEffect } from 'react' ;
22import { Line } from 'react-chartjs-2' ;
33import { ResizablePanel } from './ResizablePanel' ;
44import {
@@ -12,6 +12,7 @@ import {
1212 Tooltip ,
1313 Legend ,
1414} from 'chart.js' ;
15+ import zoomPlugin from 'chartjs-plugin-zoom' ;
1516
1617ChartJS . register (
1718 CategoryScale ,
@@ -20,11 +21,12 @@ ChartJS.register(
2021 LineElement ,
2122 Title ,
2223 Tooltip ,
23- Legend
24+ Legend ,
25+ zoomPlugin
2426) ;
2527
2628// Chart wrapper component with error boundary
27- const ChartWrapper = ( { data, options, title , chartId, onRegisterChart, onSyncHover } ) => {
29+ const ChartWrapper = ( { data, options, chartId, onRegisterChart, onSyncHover } ) => {
2830 const chartRef = useRef ( null ) ;
2931
3032 const handleChartRef = useCallback ( ( ref ) => {
@@ -36,7 +38,7 @@ const ChartWrapper = ({ data, options, title, chartId, onRegisterChart, onSyncHo
3638
3739 const enhancedOptions = {
3840 ...options ,
39- onHover : ( event , activeElements , chart ) => {
41+ onHover : ( event , activeElements ) => {
4042 if ( activeElements . length > 0 ) {
4143 const step = activeElements [ 0 ] . index ;
4244 onSyncHover ( step , chartId ) ;
@@ -89,7 +91,6 @@ export default function ChartContainer({
8991 onMaxStepChange
9092} ) {
9193 // 同步hover状态管理
92- const [ syncHoverStep , setSyncHoverStep ] = useState ( null ) ;
9394 const chartRefs = useRef ( new Map ( ) ) ; // 存储所有图表实例的引用
9495
9596 // 注册图表实例
@@ -101,14 +102,13 @@ export default function ChartContainer({
101102 const syncHoverToAllCharts = useCallback ( ( step , sourceChartId ) => {
102103 if ( step === null ) {
103104 // 清除所有图表的hover状态(包括源图表)
104- chartRefs . current . forEach ( ( chart , chartId ) => {
105+ chartRefs . current . forEach ( ( chart ) => {
105106 if ( chart ) {
106107 chart . setActiveElements ( [ ] ) ;
107108 chart . tooltip . setActiveElements ( [ ] ) ;
108109 chart . update ( 'none' ) ;
109110 }
110111 } ) ;
111- setSyncHoverStep ( null ) ;
112112 } else {
113113 // 同步hover到所有图表(不包括源图表,避免重复操作)
114114 chartRefs . current . forEach ( ( chart , chartId ) => {
@@ -130,7 +130,6 @@ export default function ChartContainer({
130130 chart . update ( 'none' ) ;
131131 }
132132 } ) ;
133- setSyncHoverStep ( step ) ;
134133 }
135134 } , [ ] ) ;
136135
@@ -175,7 +174,7 @@ export default function ChartContainer({
175174 // 数值正则:支持各种数值格式,包括科学计数法
176175 const numberRegex = / [ + - ] ? \d + (?: \. \d + ) ? (?: [ e E ] [ + - ] ? \d + ) ? / ;
177176
178- lines . forEach ( ( line , lineIndex ) => {
177+ lines . forEach ( ( line ) => {
179178 // 查找关键词(忽略大小写)
180179 const keywordIndex = line . toLowerCase ( ) . indexOf ( keyword . toLowerCase ( ) ) ;
181180 if ( keywordIndex !== - 1 ) {
@@ -204,7 +203,7 @@ export default function ChartContainer({
204203 } else {
205204 // 正则表达式匹配
206205 const lossRegexObj = new RegExp ( fileLossConfig . regex ) ;
207- lines . forEach ( ( line , index ) => {
206+ lines . forEach ( ( line ) => {
208207 lossRegexObj . lastIndex = 0 ;
209208 const lossMatch = lossRegexObj . exec ( line ) ;
210209 if ( lossMatch && lossMatch [ 1 ] ) {
@@ -226,7 +225,7 @@ export default function ChartContainer({
226225 // 数值正则:支持各种数值格式,包括科学计数法
227226 const numberRegex = / [ + - ] ? \d + (?: \. \d + ) ? (?: [ e E ] [ + - ] ? \d + ) ? / ;
228227
229- lines . forEach ( ( line , lineIndex ) => {
228+ lines . forEach ( ( line ) => {
230229 // 查找关键词(忽略大小写)
231230 const keywordIndex = line . toLowerCase ( ) . indexOf ( keyword . toLowerCase ( ) ) ;
232231 if ( keywordIndex !== - 1 ) {
@@ -255,7 +254,7 @@ export default function ChartContainer({
255254 } else {
256255 // 正则表达式匹配
257256 const gradNormRegexObj = new RegExp ( fileGradNormConfig . regex ) ;
258- lines . forEach ( ( line , index ) => {
257+ lines . forEach ( ( line ) => {
259258 gradNormRegexObj . lastIndex = 0 ;
260259 const gradNormMatch = gradNormRegexObj . exec ( line ) ;
261260 if ( gradNormMatch && gradNormMatch [ 1 ] ) {
@@ -318,15 +317,6 @@ export default function ChartContainer({
318317 onMaxStepChange ( maxStep ) ;
319318 } , [ parsedData , onMaxStepChange ] ) ;
320319
321- const movingAverage = ( data , windowSize = 10 ) => {
322- return data . map ( ( point , index ) => {
323- const start = Math . max ( 0 , index - windowSize + 1 ) ;
324- const end = index + 1 ;
325- const window = data . slice ( start , end ) ;
326- const avg = window . reduce ( ( sum , p ) => sum + p . y , 0 ) / window . length ;
327- return { x : point . x , y : avg } ;
328- } ) ;
329- } ;
330320
331321 const getComparisonData = ( data1 , data2 , mode ) => {
332322 const minLength = Math . min ( data1 . length , data2 . length ) ;
@@ -341,11 +331,12 @@ export default function ChartContainer({
341331 case 'absolute' :
342332 diff = Math . abs ( val2 - val1 ) ;
343333 break ;
344- case 'relative' :
334+ case 'relative' : {
345335 // 相对误差:先计算绝对差值,再计算相对误差(不使用百分号)
346336 const absoluteDiff = Math . abs ( val2 - val1 ) ;
347- diff = val1 !== 0 ? ( absoluteDiff / Math . abs ( val1 ) ) : 0 ;
337+ diff = val1 !== 0 ? absoluteDiff / Math . abs ( val1 ) : 0 ;
348338 break ;
339+ }
349340 default : // normal
350341 diff = val2 - val1 ;
351342 }
@@ -526,7 +517,7 @@ export default function ChartContainer({
526517 '#f97316' , // orange
527518 ] ;
528519
529- const createChartData = ( dataArray , title , yAxisLabel ) => {
520+ const createChartData = ( dataArray ) => {
530521 const datasets = [ ] ;
531522
532523 dataArray . forEach ( ( item , index ) => {
@@ -691,7 +682,7 @@ export default function ChartContainer({
691682 chartId = "loss-main"
692683 onRegisterChart = { registerChart }
693684 onSyncHover = { syncHoverToAllCharts }
694- data = { createChartData ( lossDataArray , 'Loss' , 'Loss Value' ) }
685+ data = { createChartData ( lossDataArray ) }
695686 options = { {
696687 ...chartOptions ,
697688 scales : {
@@ -705,7 +696,6 @@ export default function ChartContainer({
705696 } ,
706697 } ,
707698 } }
708- title = "Loss Function"
709699 />
710700 </ ResizablePanel >
711701 ) }
@@ -731,7 +721,6 @@ export default function ChartContainer({
731721 } ,
732722 } ,
733723 } }
734- title = "Loss Comparison"
735724 />
736725 </ ResizablePanel >
737726 ) }
@@ -747,7 +736,7 @@ export default function ChartContainer({
747736 chartId = "gradnorm-main"
748737 onRegisterChart = { registerChart }
749738 onSyncHover = { syncHoverToAllCharts }
750- data = { createChartData ( gradNormDataArray , 'Grad Norm' , 'Grad Norm Value' ) }
739+ data = { createChartData ( gradNormDataArray ) }
751740 options = { {
752741 ...chartOptions ,
753742 scales : {
@@ -761,7 +750,6 @@ export default function ChartContainer({
761750 } ,
762751 } ,
763752 } }
764- title = "Gradient Norm"
765753 />
766754 </ ResizablePanel >
767755 ) }
@@ -787,7 +775,6 @@ export default function ChartContainer({
787775 } ,
788776 } ,
789777 } }
790- title = "Grad Norm Comparison"
791778 />
792779 </ ResizablePanel >
793780 ) }
0 commit comments