1- import { useState , useRef } from 'react' ;
1+ import { useState , useRef , useMemo , useCallback } from 'react' ;
22import {
33 Bar ,
44 BarChart as RechartsBarChart ,
@@ -13,7 +13,7 @@ import { Stack } from '../../../spacing';
1313import { chartColors , ChartColors , fontSize } from '../../../style/theme' ;
1414import { useChartLegend } from '../legend/ChartLegendWrapper' ;
1515import { BarchartTooltip } from './BarchartTooltip' ;
16- import { formatToISONumber , getTicks } from '../common/chartUtils' ;
16+ import { formatTickValue , getTicks } from '../common/chartUtils' ;
1717import { useChartData } from './Barchart.utils' ;
1818import {
1919 ChartHeader ,
@@ -112,15 +112,19 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
112112 } = props ;
113113
114114 // Create colorSet from ChartLegendWrapper
115- const colorSet = bars ?. reduce (
116- ( acc , bar ) => {
117- const color = getColor ( bar . label ) ;
118- if ( color ) {
119- acc [ bar . label ] = color ;
120- }
121- return acc ;
122- } ,
123- { } as Record < string , ChartColors | string > ,
115+ const colorSet = useMemo (
116+ ( ) =>
117+ bars ?. reduce (
118+ ( acc , bar ) => {
119+ const color = getColor ( bar . label ) ;
120+ if ( color ) {
121+ acc [ bar . label ] = color ;
122+ }
123+ return acc ;
124+ } ,
125+ { } as Record < string , ChartColors | string > ,
126+ ) ,
127+ [ bars , getColor ] ,
124128 ) ;
125129
126130 const {
@@ -139,6 +143,113 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
139143 stackedBarSort ,
140144 ) ;
141145 const titleWithUnit = unitLabel ? `${ title } (${ unitLabel } )` : title ;
146+
147+ const tickFormatter = useCallback (
148+ ( value : number ) => formatTickValue ( value , roundReferenceValue ) ,
149+ [ roundReferenceValue ] ,
150+ ) ;
151+
152+ const renderChartContent = ( ) => {
153+ if ( isError || ( ! bars && ! isLoading ) ) {
154+ return < ChartError height = { height } /> ;
155+ }
156+ if ( isLoading ) {
157+ return < ChartLoading height = { height } /> ;
158+ }
159+
160+ return (
161+ < StyledResponsiveContainer ref = { chartRef } width = "100%" height = { height } >
162+ < RechartsBarChart
163+ data = { rechartsData }
164+ accessibilityLayer
165+ barSize = {
166+ type . type === 'category'
167+ ? type . gap === 0
168+ ? undefined
169+ : CHART_CONSTANTS . BAR_SIZE
170+ : CHART_CONSTANTS . BAR_SIZE
171+ }
172+ height = { height }
173+ margin = { CHART_CONSTANTS . CHART_MARGIN }
174+ barCategoryGap = { type . type === 'category' ? type . gap : undefined }
175+ >
176+ < CartesianGrid
177+ vertical = { true }
178+ horizontal = { true }
179+ verticalPoints = { [ 0 ] }
180+ horizontalPoints = { [ 0 ] }
181+ stroke = { theme . border }
182+ fill = { theme . backgroundLevel4 }
183+ strokeWidth = { 1 }
184+ />
185+ { rechartsBars . map ( ( bar ) => {
186+ const { fill, dataKey, stackId } = bar ;
187+ return (
188+ < Bar
189+ key = { dataKey }
190+ dataKey = { dataKey }
191+ fill = { chartColors [ fill ] || fill }
192+ minPointSize = { stacked ? 0 : CHART_CONSTANTS . MIN_POINT_SIZE }
193+ stackId = { stackId }
194+ isAnimationActive = { false }
195+ onMouseOver = { ( ) => setHoveredValue ( dataKey ) }
196+ onMouseLeave = { ( ) => setHoveredValue ( undefined ) }
197+ />
198+ ) ;
199+ } ) }
200+
201+ < YAxis
202+ interval = { 0 }
203+ domain = { [ 0 , topDomain ] }
204+ ticks = { getTicks ( roundReferenceValue , false ) }
205+ tickFormatter = { tickFormatter }
206+ axisLine = { { stroke : theme . border } }
207+ tick = { {
208+ fill : theme . textSecondary ,
209+ fontSize : fontSize . smaller ,
210+ } }
211+ orientation = "right"
212+ />
213+
214+ < XAxis
215+ dataKey = "category"
216+ tick = { ( props ) => (
217+ < CustomTick
218+ { ...props }
219+ type = { type }
220+ tickWidthOffset = { CHART_CONSTANTS . TICK_WIDTH_OFFSET }
221+ />
222+ ) }
223+ type = "category"
224+ interval = { 0 }
225+ allowDataOverflow = { true }
226+ tickLine = { {
227+ stroke : theme . border ,
228+ } }
229+ axisLine = { {
230+ stroke : theme . border ,
231+ } }
232+ />
233+
234+ < Tooltip
235+ content = { ( props : TooltipContentProps < number , string > ) => (
236+ < BarchartTooltip
237+ type = { type }
238+ colorSet = { colorSet }
239+ tooltipProps = { props }
240+ hoveredValue = { hoveredValue }
241+ tooltip = { tooltip }
242+ unitLabel = { unitLabel }
243+ chartContainerRef = { chartRef }
244+ />
245+ ) }
246+ cursor = { false }
247+ />
248+ </ RechartsBarChart >
249+ </ StyledResponsiveContainer >
250+ ) ;
251+ } ;
252+
142253 return (
143254 < Stack direction = "vertical" style = { { gap : '0' } } >
144255 < ChartHeader
@@ -147,101 +258,7 @@ export const Barchart = <T extends BarchartBars>(props: BarchartProps<T>) => {
147258 helpTooltip = { helpTooltip }
148259 rightTitle = { rightTitle }
149260 />
150- { isError || ( ! bars && ! isLoading ) ? (
151- < ChartError height = { height } />
152- ) : isLoading ? (
153- < ChartLoading height = { height } />
154- ) : (
155- < StyledResponsiveContainer ref = { chartRef } width = "100%" height = { height } >
156- < RechartsBarChart
157- data = { rechartsData }
158- accessibilityLayer
159- barSize = {
160- type . type === 'category'
161- ? type . gap === 0
162- ? undefined
163- : CHART_CONSTANTS . BAR_SIZE
164- : CHART_CONSTANTS . BAR_SIZE
165- }
166- height = { height }
167- margin = { CHART_CONSTANTS . CHART_MARGIN }
168- barCategoryGap = { type . type === 'category' ? type . gap : undefined }
169- >
170- < CartesianGrid
171- vertical = { true }
172- horizontal = { true }
173- verticalPoints = { [ 0 ] }
174- horizontalPoints = { [ 0 ] }
175- stroke = { theme . border }
176- fill = { theme . backgroundLevel4 }
177- strokeWidth = { 1 }
178- />
179- { rechartsBars . map ( ( bar ) => {
180- const { fill, dataKey, stackId } = bar ;
181- return (
182- < Bar
183- key = { dataKey }
184- dataKey = { dataKey }
185- fill = { chartColors [ fill ] || fill }
186- minPointSize = { stacked ? 0 : CHART_CONSTANTS . MIN_POINT_SIZE }
187- stackId = { stackId }
188- isAnimationActive = { false }
189- onMouseOver = { ( ) => setHoveredValue ( dataKey ) }
190- onMouseLeave = { ( ) => setHoveredValue ( undefined ) }
191- />
192- ) ;
193- } ) }
194-
195- < YAxis
196- interval = { 0 }
197- domain = { [ 0 , topDomain ] }
198- ticks = { getTicks ( roundReferenceValue , false ) }
199- tickFormatter = { ( value ) => formatToISONumber ( value ) }
200- axisLine = { { stroke : theme . border } }
201- tick = { {
202- fill : theme . textSecondary ,
203- fontSize : fontSize . smaller ,
204- } }
205- orientation = "right"
206- />
207-
208- < XAxis
209- dataKey = "category"
210- tick = { ( props ) => (
211- < CustomTick
212- { ...props }
213- type = { type }
214- tickWidthOffset = { CHART_CONSTANTS . TICK_WIDTH_OFFSET }
215- />
216- ) }
217- type = "category"
218- interval = { 0 }
219- allowDataOverflow = { true }
220- tickLine = { {
221- stroke : theme . border ,
222- } }
223- axisLine = { {
224- stroke : theme . border ,
225- } }
226- />
227-
228- < Tooltip
229- content = { ( props : TooltipContentProps < number , string > ) => (
230- < BarchartTooltip
231- type = { type }
232- colorSet = { colorSet }
233- tooltipProps = { props }
234- hoveredValue = { hoveredValue }
235- tooltip = { tooltip }
236- unitLabel = { unitLabel }
237- chartContainerRef = { chartRef }
238- />
239- ) }
240- cursor = { false }
241- />
242- </ RechartsBarChart >
243- </ StyledResponsiveContainer >
244- ) }
261+ { renderChartContent ( ) }
245262 </ Stack >
246263 ) ;
247264} ;
0 commit comments