@@ -6,13 +6,19 @@ import ChartKit, {settings} from '@gravity-ui/chartkit';
66import type { IResponseError } from '../../types/api/error' ;
77import type { TimeFrame } from '../../utils/timeframes' ;
88import { useAutofetcher } from '../../utils/hooks' ;
9+
910import { COLORS } from '../../utils/versions' ;
1011import { cn } from '../../utils/cn' ;
1112
1213import { Loader } from '../Loader' ;
1314import { ResponseError } from '../Errors/ResponseError' ;
1415
15- import type { ChartOptions , MetricDescription , PreparedMetricsData } from './types' ;
16+ import type {
17+ ChartOptions ,
18+ MetricDescription ,
19+ OnChartDataStatusChange ,
20+ PreparedMetricsData ,
21+ } from './types' ;
1622import { convertResponse } from './convertReponse' ;
1723import { getDefaultDataFormatter } from './getDefaultDataFormatter' ;
1824import { getChartData } from './getChartData' ;
@@ -102,6 +108,15 @@ interface DiagnosticsChartProps {
102108 width ?: number ;
103109
104110 chartOptions ?: ChartOptions ;
111+
112+ onChartDataStatusChange ?: OnChartDataStatusChange ;
113+
114+ /**
115+ * YAGR charts don't render correctly inside not visible elements\
116+ * So if chart is used inside component with 'display:none', it will be empty, when visibility change\
117+ * Pass isChartVisible prop to ensure proper chart render
118+ */
119+ isChartVisible ?: boolean ;
105120}
106121
107122export const MetricChart = ( {
@@ -112,6 +127,8 @@ export const MetricChart = ({
112127 width = 400 ,
113128 height = width / 1.5 ,
114129 chartOptions,
130+ onChartDataStatusChange,
131+ isChartVisible,
115132} : DiagnosticsChartProps ) => {
116133 const mounted = useRef ( false ) ;
117134
@@ -127,6 +144,20 @@ export const MetricChart = ({
127144 initialChartState ,
128145 ) ;
129146
147+ useEffect ( ( ) => {
148+ if ( error ) {
149+ return onChartDataStatusChange ?.( 'error' ) ;
150+ }
151+ if ( loading && ! wasLoaded ) {
152+ return onChartDataStatusChange ?.( 'loading' ) ;
153+ }
154+ if ( ! loading && wasLoaded ) {
155+ return onChartDataStatusChange ?.( 'success' ) ;
156+ }
157+
158+ return undefined ;
159+ } , [ loading , wasLoaded , error , onChartDataStatusChange ] ) ;
160+
130161 const fetchChartData = useCallback (
131162 async ( isBackground : boolean ) => {
132163 dispatch ( setChartDataLoading ( ) ) ;
@@ -146,7 +177,9 @@ export const MetricChart = ({
146177 } ) ;
147178
148179 // Hack to prevent setting value to state, if component unmounted
149- if ( ! mounted . current ) return ;
180+ if ( ! mounted . current ) {
181+ return ;
182+ }
150183
151184 // In some cases error could be in response with 200 status code
152185 // It happens when request is OK, but chart data cannot be returned due to some reason
@@ -155,10 +188,14 @@ export const MetricChart = ({
155188 const preparedData = convertResponse ( response , metrics ) ;
156189 dispatch ( setChartData ( preparedData ) ) ;
157190 } else {
158- dispatch ( setChartError ( { statusText : response . error } ) ) ;
191+ const err = { statusText : response . error } ;
192+
193+ throw err ;
159194 }
160195 } catch ( err ) {
161- if ( ! mounted . current ) return ;
196+ if ( ! mounted . current ) {
197+ return ;
198+ }
162199
163200 dispatch ( setChartError ( err as IResponseError ) ) ;
164201 }
@@ -175,6 +212,10 @@ export const MetricChart = ({
175212 return < Loader /> ;
176213 }
177214
215+ if ( ! isChartVisible ) {
216+ return null ;
217+ }
218+
178219 return (
179220 < div className = { b ( 'chart' ) } >
180221 < ChartKit type = "yagr" data = { convertedData } />
0 commit comments