tracesChart.tsx 2.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. import {useMemo} from 'react';
  2. import styled from '@emotion/styled';
  3. import {getInterval} from 'sentry/components/charts/utils';
  4. import {t} from 'sentry/locale';
  5. import {RateUnit} from 'sentry/utils/discover/fields';
  6. import {formatRate} from 'sentry/utils/formatters';
  7. import {decodeList} from 'sentry/utils/queryString';
  8. import {MutableSearch} from 'sentry/utils/tokenizeSearch';
  9. import {useLocation} from 'sentry/utils/useLocation';
  10. import usePageFilters from 'sentry/utils/usePageFilters';
  11. import {CHART_HEIGHT} from 'sentry/views/performance/database/settings';
  12. import {COUNT_COLOR} from 'sentry/views/starfish/colors';
  13. import Chart, {ChartType} from 'sentry/views/starfish/components/chart';
  14. import ChartPanel from 'sentry/views/starfish/components/chartPanel';
  15. import {useSpanIndexedSeries} from 'sentry/views/starfish/queries/useDiscoverSeries';
  16. import {areQueriesEmpty} from './utils';
  17. interface Props {}
  18. export function TracesChart({}: Props) {
  19. const location = useLocation();
  20. const pageFilters = usePageFilters();
  21. const queries = useMemo(() => {
  22. return decodeList(location.query.query);
  23. }, [location.query.query]);
  24. const spanIndexedCountSeries = useSpanIndexedSeries(
  25. {
  26. search: new MutableSearch(
  27. queries
  28. .filter(Boolean)
  29. .map(q => `(${q})`)
  30. .join(' OR ')
  31. ),
  32. yAxis: ['count()'],
  33. interval: getInterval(pageFilters.selection.datetime, 'metrics'),
  34. overriddenRoute: 'traces-stats',
  35. },
  36. 'api.trace-explorer.stats'
  37. );
  38. const seriesData = spanIndexedCountSeries.data?.['count()'];
  39. seriesData.z = 1; // TODO:: This shouldn't be required, but we're putting this in for now to avoid split lines being shown on top of the chart data :).
  40. return (
  41. <ChartContainer>
  42. <ChartPanel
  43. title={areQueriesEmpty(queries) ? t('Total Spans') : t('Matching Spans')}
  44. >
  45. <Chart
  46. height={CHART_HEIGHT}
  47. grid={{
  48. left: '0',
  49. right: '0',
  50. top: '8px',
  51. bottom: '0',
  52. }}
  53. data={[seriesData]}
  54. loading={spanIndexedCountSeries.isLoading}
  55. chartColors={[COUNT_COLOR]}
  56. type={ChartType.AREA}
  57. aggregateOutputFormat="number"
  58. tooltipFormatterOptions={{
  59. valueFormatter: value => formatRate(value, RateUnit.PER_MINUTE),
  60. }}
  61. preserveIncompletePoints
  62. />
  63. </ChartPanel>
  64. </ChartContainer>
  65. );
  66. }
  67. const ChartContainer = styled('div')`
  68. display: grid;
  69. gap: 0;
  70. grid-template-columns: 1fr;
  71. `;