useSpanMetricsTopNSeries.tsx 2.2 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182
  1. import type {Series} from 'sentry/types/echarts';
  2. import type {MutableSearch} from 'sentry/utils/tokenizeSearch';
  3. import usePageFilters from 'sentry/utils/usePageFilters';
  4. import {getSeriesEventView} from 'sentry/views/starfish/queries/getSeriesEventView';
  5. import type {SpanMetricsProperty} from 'sentry/views/starfish/types';
  6. import {useWrappedDiscoverTimeseriesQuery} from 'sentry/views/starfish/utils/useSpansQuery';
  7. interface SpanMetricTimeseriesRow {
  8. [key: string]: number;
  9. interval: number;
  10. }
  11. interface UseSpanMetricsSeriesOptions<Fields> {
  12. topEvents: number;
  13. enabled?: boolean;
  14. fields?: Fields;
  15. referrer?: string;
  16. search?: MutableSearch;
  17. yAxis?: Fields;
  18. }
  19. export const useSpanMetricsTopNSeries = <Fields extends SpanMetricsProperty[]>(
  20. options: UseSpanMetricsSeriesOptions<Fields> = {topEvents: DEFAULT_EVENT_COUNT}
  21. ) => {
  22. const {
  23. search = undefined,
  24. fields = [],
  25. yAxis = [],
  26. topEvents,
  27. referrer = 'span-metrics-top-n-series',
  28. } = options;
  29. if (yAxis.length > 1) {
  30. throw new Error(
  31. 'Multi-axis top-N queries are not supported by this hook. Try using `useSpansQuery` directly.'
  32. );
  33. }
  34. const pageFilters = usePageFilters();
  35. const eventView = getSeriesEventView(
  36. search,
  37. fields,
  38. pageFilters.selection,
  39. yAxis,
  40. topEvents
  41. );
  42. const result = useWrappedDiscoverTimeseriesQuery<SpanMetricTimeseriesRow[]>({
  43. eventView,
  44. initialData: [],
  45. referrer,
  46. enabled: options.enabled,
  47. });
  48. const seriesByKey: {[key: string]: Series} = {};
  49. (result?.data ?? []).forEach(datum => {
  50. // `interval` is the timestamp of the data point. Every other key is the value of a requested or found timeseries. `groups` is used to disambiguate top-N multi-axis series, which aren't supported here so the value is useless
  51. const {interval, group: _group, ...data} = datum;
  52. Object.keys(data).forEach(key => {
  53. const value = {
  54. name: interval,
  55. value: datum[key],
  56. };
  57. if (seriesByKey[key]) {
  58. seriesByKey[key].data.push(value);
  59. } else {
  60. seriesByKey[key] = {
  61. seriesName: key,
  62. data: [value],
  63. };
  64. }
  65. });
  66. });
  67. return {...result, data: seriesByKey as {[key: string]: Series}};
  68. };
  69. const DEFAULT_EVENT_COUNT = 5;