1- import * as _ from 'lodash-es' ;
2- import classNames from 'classnames' ;
3- import * as React from 'react' ;
41import {
52 PrometheusEndpoint ,
63 PrometheusLabels ,
@@ -22,28 +19,32 @@ import {
2219import {
2320 Alert ,
2421 Button ,
22+ Card ,
23+ CardBody ,
24+ CardHeader ,
2525 Checkbox ,
2626 Dropdown ,
2727 DropdownItem ,
2828 DropdownList ,
2929 EmptyState ,
3030 EmptyStateBody ,
3131 EmptyStateVariant ,
32- MenuToggle ,
33- MenuToggleElement ,
3432 InputGroup ,
35- TextInput ,
36- Title ,
3733 InputGroupItem ,
38- Card ,
39- CardHeader ,
40- Split ,
41- SplitItem ,
4234 Level ,
4335 LevelItem ,
44- CardBody ,
36+ MenuToggle ,
37+ MenuToggleElement ,
38+ Split ,
39+ SplitItem ,
40+ TextInput ,
41+ Title ,
42+ Tooltip ,
4543} from '@patternfly/react-core' ;
4644import { ChartLineIcon } from '@patternfly/react-icons' ;
45+ import classNames from 'classnames' ;
46+ import * as _ from 'lodash-es' ;
47+ import * as React from 'react' ;
4748import { useTranslation } from 'react-i18next' ;
4849import { useDispatch , useSelector } from 'react-redux' ;
4950
@@ -69,24 +70,24 @@ import { queryBrowserTheme } from './query-browser-theme';
6970import { PrometheusAPIError , TimeRange } from './types' ;
7071import { getTimeRanges } from './utils' ;
7172
72- import { getLegacyObserveState , getObserveState , usePerspective } from './hooks/usePerspective' ;
73- import { MonitoringState } from '../reducers/observe' ;
74- import { LoadingInline } from './console/console-shared/src/components/loading/LoadingInline' ;
73+ import { CustomDataSource } from '@openshift-console/dynamic-plugin-sdk/lib/extensions/dashboard-data-source' ;
7574import {
76- formatPrometheusDuration ,
77- parsePrometheusDuration ,
78- } from './console/console-shared/src/datetime/prometheus' ;
75+ chart_area_Opacity ,
76+ chart_axis_tick_Size ,
77+ t_chart_global_fill_color_200 ,
78+ } from '@patternfly/react-tokens' ;
79+ import { MonitoringState } from '../reducers/observe' ;
7980import withFallback from './console/console-shared/error/fallbacks/withFallback' ;
80- import { CustomDataSource } from '@openshift- console/dynamic-plugin-sdk/lib/extensions/dashboard-data-source ' ;
81+ import { LoadingInline } from './ console/console-shared/src/components/loading/LoadingInline ' ;
8182import {
8283 QueryBrowserTooltip ,
8384 valueFormatter ,
8485} from './console/console-shared/src/components/query-browser/QueryBrowserTooltip' ;
8586import {
86- chart_area_Opacity ,
87- chart_axis_tick_Size ,
88- t_chart_global_fill_color_200 ,
89- } from '@patternfly/react-tokens ' ;
87+ formatPrometheusDuration ,
88+ parsePrometheusDuration ,
89+ } from './console/console-shared/src/datetime/prometheus' ;
90+ import { getLegacyObserveState , getObserveState , usePerspective } from './hooks/usePerspective ' ;
9091import './query-browser.scss' ;
9192import { GraphUnits } from './metrics/units' ;
9293
@@ -416,7 +417,9 @@ const formatSeriesValues = (
416417 samples : number ,
417418 span : number ,
418419 defaultEmptyValue : 0 | null ,
419- ) : GraphDataPoint [ ] => {
420+ createGaps : boolean ,
421+ ) : { points : GraphDataPoint [ ] ; hasDisconnectedValues : boolean } => {
422+ let hasDisconnectedValues = false ;
420423 const newValues = _ . map ( values , ( v ) => {
421424 const y = Number ( v [ 1 ] ) ;
422425 return {
@@ -425,19 +428,23 @@ const formatSeriesValues = (
425428 } ;
426429 } ) ;
427430
428- // The data may have missing values, so we fill those gaps with nulls so that the graph correctly
431+ // The data may have missing values, if disconnected is enabled,
432+ // we fill those gaps with nulls so that the graph correctly
429433 // shows the missing values as gaps in the line
430434 const start = Number ( _ . get ( newValues , '[0].x' ) ) ;
431435 const end = Number ( _ . get ( _ . last ( newValues ) , 'x' ) ) ;
432436 const step = span / samples ;
433437 _ . range ( start , end , step ) . forEach ( ( t , i ) => {
434438 const x = new Date ( t ) ;
435439 if ( _ . get ( newValues , [ i , 'x' ] ) > x ) {
436- newValues . splice ( i , 0 , { x, y : null } ) ;
440+ hasDisconnectedValues = true ;
441+ if ( createGaps ) {
442+ newValues . splice ( i , 0 , { x, y : null } ) ;
443+ }
437444 }
438445 } ) ;
439446
440- return newValues ;
447+ return { points : newValues , hasDisconnectedValues } ;
441448} ;
442449
443450// Try to limit the graph to this number of data points
@@ -582,6 +589,7 @@ const QueryBrowser_: React.FC<QueryBrowserProps> = ({
582589 queries,
583590 showLegend,
584591 showStackedControl = false ,
592+ showDisconnectedControl = true ,
585593 timespan,
586594 units,
587595 onDataChange,
@@ -627,6 +635,8 @@ const QueryBrowser_: React.FC<QueryBrowserProps> = ({
627635 const safeFetch = useSafeFetch ( ) ;
628636
629637 const [ isStacked , setIsStacked ] = React . useState ( isStack ) ;
638+ const [ showDisconnectedValues , setIsShowDisconnectedValues ] = React . useState ( false ) ;
639+ const [ isDisconnectedEnabled , setIsDisconnectedEnabled ] = React . useState ( true ) ;
630640
631641 const canStack = _ . sumBy ( graphData , 'length' ) <= maxStacks ;
632642
@@ -738,6 +748,8 @@ const QueryBrowser_: React.FC<QueryBrowserProps> = ({
738748 maxSamplesForSpan ,
739749 ) ;
740750
751+ let dataIsDisconnected = false ;
752+
741753 // Change `samples` if either
742754 // - It will change by a proportion greater than `samplesLeeway`
743755 // - It will change to the upper or lower limit of its allowed range
@@ -765,14 +777,26 @@ const QueryBrowser_: React.FC<QueryBrowserProps> = ({
765777 ) ;
766778 defaultEmptyValue = 0 ;
767779 }
768- return [ metric , formatSeriesValues ( values , samples , span , defaultEmptyValue ) ] ;
780+ const { points, hasDisconnectedValues } = formatSeriesValues (
781+ values ,
782+ samples ,
783+ span ,
784+ defaultEmptyValue ,
785+ showDisconnectedValues ,
786+ ) ;
787+
788+ dataIsDisconnected = hasDisconnectedValues ;
789+
790+ return [ metric , points ] ;
769791 }
770792 } ) ;
771793 } ,
772794 ) ;
773795 setGraphData ( newGraphData ) ;
774796 onDataChange ?.( newGraphData ) ;
775797
798+ setIsDisconnectedEnabled ( dataIsDisconnected ) ;
799+
776800 _ . each ( newResults , ( r , i ) =>
777801 dispatch ( queryBrowserPatchQuery ( i , { series : r ? _ . map ( r , 'metric' ) : undefined } ) ) ,
778802 ) ;
@@ -816,6 +840,7 @@ const QueryBrowser_: React.FC<QueryBrowserProps> = ({
816840 samples ,
817841 span ,
818842 lastRequestTime ,
843+ showDisconnectedValues ,
819844 ) ;
820845
821846 React . useLayoutEffect (
@@ -909,18 +934,52 @@ const QueryBrowser_: React.FC<QueryBrowserProps> = ({
909934 </ SplitItem >
910935 < SplitItem isFilled />
911936 < SplitItem >
912- { GraphLink && < GraphLink /> }
913- { canStack && showStackedControl && (
914- < Checkbox
915- id = "stacked"
916- isChecked = { isStacked }
917- data-checked-state = { isStacked }
918- label = { t ( 'Stacked' ) }
919- onChange = { ( _e , v ) =>
920- typeof _e === 'boolean' ? setIsStacked ( _e ) : setIsStacked ( v )
921- }
922- />
923- ) }
937+ < Split hasGutter >
938+ { GraphLink && (
939+ < SplitItem >
940+ < GraphLink />
941+ </ SplitItem >
942+ ) }
943+ { canStack && showStackedControl && (
944+ < SplitItem >
945+ < Checkbox
946+ id = "stacked"
947+ isChecked = { isStacked }
948+ data-checked-state = { isStacked }
949+ label = { t ( 'Stacked' ) }
950+ onChange = { ( _e , v ) =>
951+ typeof _e === 'boolean' ? setIsStacked ( _e ) : setIsStacked ( v )
952+ }
953+ />
954+ </ SplitItem >
955+ ) }
956+ { showDisconnectedControl && (
957+ < SplitItem >
958+ < Tooltip
959+ content = {
960+ < div >
961+ { isDisconnectedEnabled
962+ ? t ( 'Check to show gaps for missing data' )
963+ : t ( 'No gaps found in the data' ) }
964+ </ div >
965+ }
966+ >
967+ < Checkbox
968+ id = "disconnected"
969+ isChecked = { isDisconnectedEnabled && showDisconnectedValues }
970+ data-checked-state = { isDisconnectedEnabled && showDisconnectedValues }
971+ label = { t ( 'Disconnected' ) }
972+ onChange = { ( _e , v ) =>
973+ typeof _e === 'boolean'
974+ ? setIsShowDisconnectedValues ( _e )
975+ : setIsShowDisconnectedValues ( v )
976+ }
977+ isDisabled = { ! isDisconnectedEnabled }
978+ />
979+ </ Tooltip >
980+ </ SplitItem >
981+ ) }
982+ </ Split >
924983 </ SplitItem >
925984 </ Split >
926985 </ CardHeader >
@@ -1029,6 +1088,7 @@ export type QueryBrowserProps = {
10291088 queries : string [ ] ;
10301089 showLegend ?: boolean ;
10311090 showStackedControl ?: boolean ;
1091+ showDisconnectedControl ?: boolean ;
10321092 timespan ?: number ;
10331093 units ?: GraphUnits ;
10341094 onDataChange ?: ( data : any ) => void ;
0 commit comments