@@ -81,8 +81,8 @@ export default function BudgetBarChart({ data, title, description, stacked = fal
8181 // Check if we should show net impact line (only when multiple policies have data)
8282 const showNetImpact = stacked && activePolicies . length > 1 ;
8383
84- // Calculate Y-axis domain with padding (only for active/selected policies)
85- const calculateYDomain = ( ) => {
84+ // Calculate symmetric Y-axis domain with round number increments
85+ const calculateYAxisConfig = ( ) => {
8686 let minVal = 0 , maxVal = 0 ;
8787 data . forEach ( d => {
8888 let negSum = 0 , posSum = 0 ;
@@ -94,11 +94,35 @@ export default function BudgetBarChart({ data, title, description, stacked = fal
9494 minVal = Math . min ( minVal , negSum ) ;
9595 maxVal = Math . max ( maxVal , posSum ) ;
9696 } ) ;
97- // Add 15% padding
98- const padding = Math . max ( Math . abs ( minVal ) , Math . abs ( maxVal ) ) * 0.15 ;
99- return [ Math . floor ( ( minVal - padding ) / 20 ) * 20 , Math . ceil ( ( maxVal + padding ) / 20 ) * 20 ] ;
97+
98+ // Find the max absolute value
99+ const maxAbs = Math . max ( Math . abs ( minVal ) , Math . abs ( maxVal ) ) ;
100+
101+ // Choose a nice round interval based on data range
102+ let interval ;
103+ if ( maxAbs <= 100 ) interval = 50 ;
104+ else if ( maxAbs <= 200 ) interval = 50 ;
105+ else if ( maxAbs <= 400 ) interval = 100 ;
106+ else interval = 150 ;
107+
108+ // Round up to nice number for symmetric axis
109+ const roundedMax = Math . ceil ( ( maxAbs * 1.1 ) / interval ) * interval || interval ;
110+
111+ // Generate ticks from -roundedMax to +roundedMax, always including 0
112+ const ticks = [ ] ;
113+ for ( let i = - roundedMax ; i <= roundedMax ; i += interval ) {
114+ ticks . push ( i ) ;
115+ }
116+
117+ return {
118+ domain : [ - roundedMax , roundedMax ] ,
119+ ticks : ticks
120+ } ;
100121 } ;
101- const yDomain = stacked ? calculateYDomain ( ) : [ 'auto' , 'auto' ] ;
122+
123+ const yAxisConfig = stacked ? calculateYAxisConfig ( ) : { domain : [ 'auto' , 'auto' ] , ticks : undefined } ;
124+ const yDomain = yAxisConfig . domain ;
125+ const yTicks = yAxisConfig . ticks ;
102126
103127 return (
104128 < div className = "budget-bar-chart" >
@@ -119,13 +143,14 @@ export default function BudgetBarChart({ data, title, description, stacked = fal
119143 />
120144 < YAxis
121145 domain = { yDomain }
146+ ticks = { yTicks }
122147 tickFormatter = { formatValue }
123148 tick = { { fontSize : 12 } }
124149 />
125150 < Tooltip
126151 formatter = { ( value , name ) => [
127152 formatValue ( value ) ,
128- name === "netImpact " ? "Net impact" : name
153+ name === "Net impact " ? "Net impact" : name
129154 ] }
130155 labelFormatter = { formatYear }
131156 />
@@ -171,7 +196,7 @@ export default function BudgetBarChart({ data, title, description, stacked = fal
171196 stroke = "#000000"
172197 strokeWidth = { 2 }
173198 dot = { { fill : "#000000" , stroke : "#000000" , strokeWidth : 1 , r : 4 } }
174- name = "netImpact "
199+ name = "Net impact "
175200 label = { < NetImpactLabel /> }
176201 />
177202 ) }
0 commit comments