@@ -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