mirror of
https://github.com/hanzoai/sentinel.git
synced 2026-09-29 22:34:33 +00:00
174 lines
4.8 KiB
TypeScript
174 lines
4.8 KiB
TypeScript
import {useContext, useEffect} from 'react';
|
|
import type {InjectedRouter} from 'react-router';
|
|
import type {Theme} from '@emotion/react';
|
|
import type {Query} from 'history';
|
|
|
|
import {AreaChart} from 'sentry/components/charts/areaChart';
|
|
import ChartZoom from 'sentry/components/charts/chartZoom';
|
|
import ErrorPanel from 'sentry/components/charts/errorPanel';
|
|
import type {LineChartProps} from 'sentry/components/charts/lineChart';
|
|
import ReleaseSeries from 'sentry/components/charts/releaseSeries';
|
|
import TransitionChart from 'sentry/components/charts/transitionChart';
|
|
import TransparentLoadingMask from 'sentry/components/charts/transparentLoadingMask';
|
|
import Placeholder from 'sentry/components/placeholder';
|
|
import {IconWarning} from 'sentry/icons';
|
|
import type {Series} from 'sentry/types/echarts';
|
|
import {
|
|
axisLabelFormatter,
|
|
getDurationUnit,
|
|
tooltipFormatter,
|
|
} from 'sentry/utils/discover/charts';
|
|
import {aggregateOutputType} from 'sentry/utils/discover/fields';
|
|
import getDynamicText from 'sentry/utils/getDynamicText';
|
|
import {PerformanceAtScaleContext} from 'sentry/views/performance/transactionSummary/transactionOverview/performanceAtScaleContext';
|
|
|
|
type Props = {
|
|
errored: boolean;
|
|
loading: boolean;
|
|
queryExtra: Query;
|
|
reloading: boolean;
|
|
router: InjectedRouter;
|
|
theme: Theme;
|
|
series?: Series[];
|
|
timeFrame?: {
|
|
end: number;
|
|
start: number;
|
|
};
|
|
} & Omit<React.ComponentProps<typeof ReleaseSeries>, 'children' | 'queryExtra'> &
|
|
Pick<LineChartProps, 'onLegendSelectChanged' | 'legend'>;
|
|
|
|
function Content({
|
|
errored,
|
|
theme,
|
|
series: data,
|
|
timeFrame,
|
|
start,
|
|
end,
|
|
period,
|
|
projects,
|
|
environments,
|
|
loading,
|
|
reloading,
|
|
legend,
|
|
utc,
|
|
queryExtra,
|
|
router,
|
|
onLegendSelectChanged,
|
|
}: Props) {
|
|
const performanceAtScaleContext = useContext(PerformanceAtScaleContext);
|
|
const isSeriesDataEmpty = data?.every(values => {
|
|
return values.data.every(value => !value.value);
|
|
});
|
|
|
|
useEffect(() => {
|
|
if (!performanceAtScaleContext || isSeriesDataEmpty === undefined) {
|
|
return;
|
|
}
|
|
|
|
if (loading || reloading) {
|
|
performanceAtScaleContext.setMetricsSeriesDataEmpty(undefined);
|
|
return;
|
|
}
|
|
|
|
performanceAtScaleContext.setMetricsSeriesDataEmpty(isSeriesDataEmpty);
|
|
}, [loading, reloading, isSeriesDataEmpty, performanceAtScaleContext]);
|
|
|
|
if (errored) {
|
|
return (
|
|
<ErrorPanel>
|
|
<IconWarning color="gray500" size="lg" />
|
|
</ErrorPanel>
|
|
);
|
|
}
|
|
|
|
const colors = (data && theme.charts.getColorPalette(data.length - 2)) || [];
|
|
|
|
// Create a list of series based on the order of the fields,
|
|
// We need to flip it at the end to ensure the series stack right.
|
|
const series = data
|
|
? data
|
|
.map((values, i: number) => {
|
|
return {
|
|
...values,
|
|
color: colors[i],
|
|
lineStyle: {
|
|
opacity: 0,
|
|
},
|
|
};
|
|
})
|
|
.reverse()
|
|
: [];
|
|
|
|
const durationUnit = getDurationUnit(series, legend);
|
|
|
|
const chartOptions = {
|
|
grid: {
|
|
left: '10px',
|
|
right: '10px',
|
|
top: '40px',
|
|
bottom: '0px',
|
|
},
|
|
seriesOptions: {
|
|
showSymbol: false,
|
|
},
|
|
tooltip: {
|
|
trigger: 'axis' as const,
|
|
valueFormatter: (value, label) =>
|
|
tooltipFormatter(value, aggregateOutputType(label)),
|
|
},
|
|
xAxis: timeFrame
|
|
? {
|
|
min: timeFrame.start,
|
|
max: timeFrame.end,
|
|
}
|
|
: undefined,
|
|
yAxis: {
|
|
minInterval: durationUnit,
|
|
axisLabel: {
|
|
color: theme.chartLabel,
|
|
formatter: (value: number) => {
|
|
return axisLabelFormatter(value, 'duration', undefined, durationUnit);
|
|
},
|
|
},
|
|
},
|
|
};
|
|
|
|
return (
|
|
<ChartZoom router={router} period={period} start={start} end={end} utc={utc}>
|
|
{zoomRenderProps => (
|
|
<ReleaseSeries
|
|
start={start}
|
|
end={end}
|
|
queryExtra={queryExtra}
|
|
period={period}
|
|
utc={utc}
|
|
projects={projects}
|
|
environments={environments}
|
|
>
|
|
{({releaseSeries}) => {
|
|
return (
|
|
<TransitionChart loading={loading} reloading={reloading}>
|
|
<TransparentLoadingMask visible={reloading} />
|
|
{getDynamicText({
|
|
value: (
|
|
<AreaChart
|
|
{...zoomRenderProps}
|
|
{...chartOptions}
|
|
legend={legend}
|
|
onLegendSelectChanged={onLegendSelectChanged}
|
|
series={[...series, ...releaseSeries]}
|
|
/>
|
|
),
|
|
fixed: <Placeholder height="200px" testId="skeleton-ui" />,
|
|
})}
|
|
</TransitionChart>
|
|
);
|
|
}}
|
|
</ReleaseSeries>
|
|
)}
|
|
</ChartZoom>
|
|
);
|
|
}
|
|
|
|
export default Content;
|