/
PipelineRunDurationGraph.tsx
122 lines (114 loc) · 4.07 KB
/
PipelineRunDurationGraph.tsx
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
import * as React from 'react';
import { formatPrometheusDuration } from '@openshift-console/plugin-shared/src/datetime/prometheus';
import { ChartThemeColor, ChartVoronoiContainer } from '@patternfly/react-charts';
import { Bullseye, Flex, FlexItem, Grid, GridItem } from '@patternfly/react-core';
import { useTranslation } from 'react-i18next';
import Measure from 'react-measure';
import { GraphEmpty } from '@console/internal/components/graphs/graph-empty';
import { LoadingInline, truncateMiddle } from '@console/internal/components/utils';
import { DEFAULT_LEGEND_CHART_HEIGHT } from '../const';
import { usePipelineRunDurationPoll } from '../hooks';
import { LineChart } from './charts/lineChart';
import { getRangeVectorData, PipelineMetricsGraphProps } from './pipeline-metrics-utils';
import './pipeline-chart.scss';
const PipelineRunDurationGraph: React.FC<PipelineMetricsGraphProps> = ({
pipeline,
timespan,
interval,
loaded = true,
onLoad: onInitialLoad,
queryPrefix,
metricsLevel,
}) => {
const {
metadata: { name, namespace },
} = pipeline;
const { t } = useTranslation();
const [runData, runDataError, runDataLoading] = usePipelineRunDurationPoll({
name,
namespace,
timespan,
delay: interval,
queryPrefix,
metricsLevel,
});
const pipelineRunDurationData = runData?.data?.result ?? [];
const chartHeight = DEFAULT_LEGEND_CHART_HEIGHT;
React.useEffect(() => {
if (!loaded && onInitialLoad) {
onInitialLoad({
chartName: 'pipelineRunDuration',
hasData: !!pipelineRunDurationData.length,
});
}
}, [loaded, onInitialLoad, pipelineRunDurationData]);
if (runDataLoading) {
return <LoadingInline />;
}
if (
(!loaded && pipelineRunDurationData.length) ||
runDataError ||
pipelineRunDurationData.length === 0
) {
return <GraphEmpty height={chartHeight - 30} />;
}
const pRuns =
getRangeVectorData(runData, (r) => truncateMiddle(r?.metric?.pipelinerun, { length: 10 })) ??
[];
const finalArray = pRuns.reduce(
(acc, prun) => {
if (!prun) return acc;
const obj = prun[prun.length - 1];
acc.totalDuration += obj.y;
acc.duration.push({ ...obj, time: formatPrometheusDuration(obj.y * 1000) });
return acc;
},
{ totalDuration: 0, duration: [] },
);
const averageDuration = finalArray.totalDuration
? formatPrometheusDuration((finalArray.totalDuration * 1000) / finalArray.duration.length)
: 0;
return (
<Grid hasGutter>
<GridItem span={3}>
<Bullseye className="pipeline-run-average">
<Flex className="pipeline-run-average__body" spaceItems={{ default: 'spaceItemsNone' }}>
<FlexItem className="pipeline-run-average__duration">{`${averageDuration}`}</FlexItem>
<FlexItem className="pipeline-run-average__duration-desc">
{t('pipelines-plugin~Average PipelineRun duration')}
</FlexItem>
</Flex>
</Bullseye>
</GridItem>
<GridItem span={9}>
<Measure bounds>
{({ measureRef, contentRect }) => (
<div ref={measureRef}>
<LineChart
ariaDesc={t('pipelines-plugin~Pipeline run duration chart')}
data={[finalArray.duration]}
themeColor={ChartThemeColor.green}
yTickFormatter={(seconds) => `${Math.floor(seconds / 60)}m`}
width={contentRect.bounds.width}
height={chartHeight}
containerComponent={
<ChartVoronoiContainer
voronoiPadding={{ bottom: 75 } as any}
constrainToVisibleArea
activateData={false}
labels={({ datum }) =>
datum.childName.includes('line-') && datum.y !== null
? `${datum?.metric?.pipelinerun}\n${datum?.time}`
: null
}
/>
}
/>
</div>
)}
</Measure>
</GridItem>
</Grid>
);
};
export default PipelineRunDurationGraph;