@@ -214,6 +214,30 @@ export default function ChartContainer({
214
214
return result ;
215
215
} ;
216
216
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
+
217
241
const chartOptions = useMemo ( ( ) => ( {
218
242
responsive : true ,
219
243
maintainAspectRatio : false ,
@@ -326,7 +350,6 @@ export default function ChartContainer({
326
350
display : true ,
327
351
title : { display : true , text : 'Value' } ,
328
352
bounds : 'data' ,
329
- grace : '20%' ,
330
353
ticks : {
331
354
callback : function ( value ) {
332
355
return Number ( value . toPrecision ( 2 ) ) ;
@@ -429,6 +452,15 @@ export default function ChartContainer({
429
452
const dataArray = metricDataArrays [ key ] || [ ] ;
430
453
const showComparison = dataArray . length === 2 ;
431
454
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
+
432
464
let stats = null ;
433
465
if ( showComparison ) {
434
466
const normalDiff = getComparisonData ( dataArray [ 0 ] . data , dataArray [ 1 ] . data , 'normal' ) ;
@@ -442,6 +474,30 @@ export default function ChartContainer({
442
474
} ;
443
475
}
444
476
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
+
445
501
return (
446
502
< div key = { key } className = "flex flex-col gap-3" >
447
503
< ResizablePanel title = { key } initialHeight = { 440 } >
@@ -450,20 +506,10 @@ export default function ChartContainer({
450
506
onRegisterChart = { registerChart }
451
507
onSyncHover = { syncHoverToAllCharts }
452
508
data = { createChartData ( dataArray ) }
453
- options = { chartOptions }
509
+ options = { options }
454
510
/>
455
511
</ 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 }
467
513
{ stats && (
468
514
< div className = "bg-white rounded-lg shadow-md p-3" >
469
515
< h4 className = "text-sm font-medium text-gray-700 mb-1" > { key } 差值统计</ h4 >
0 commit comments