import {useState} from 'react'; import {Location} from 'history'; import {BarChart} from 'sentry/components/charts/barChart'; import BarChartZoom from 'sentry/components/charts/barChartZoom'; import ErrorPanel from 'sentry/components/charts/errorPanel'; import LoadingPanel from 'sentry/components/charts/loadingPanel'; import {IconWarning} from 'sentry/icons'; import {t} from 'sentry/locale'; import {OrganizationSummary} from 'sentry/types'; import EventView from 'sentry/utils/discover/eventView'; import Histogram from 'sentry/utils/performance/histogram'; import HistogramQuery from 'sentry/utils/performance/histogram/histogramQuery'; import {HistogramData} from 'sentry/utils/performance/histogram/types'; import { computeBuckets, formatHistogramData, } from 'sentry/utils/performance/histogram/utils'; import theme from 'sentry/utils/theme'; import {ViewProps} from '../../../types'; import {filterToColor, filterToField, SpanOperationBreakdownFilter} from '../../filter'; import {decodeHistogramZoom, ZOOM_END, ZOOM_START} from './utils'; const NUM_BUCKETS = 50; type Props = ViewProps & { currentFilter: SpanOperationBreakdownFilter; location: Location; organization: OrganizationSummary; }; /** * Fetch and render a bar chart that shows event volume * for each duration bucket. We always render 50 buckets of * equal widths based on the endpoints min + max durations. * * This graph visualizes how many transactions were recorded * at each duration bucket, showing the modality of the transaction. */ function Content({ organization, query, start, end, statsPeriod, environment, project, location, currentFilter, }: Props) { const [zoomError, setZoomError] = useState(false); function handleMouseOver() { // Hide the zoom error tooltip on the next hover. if (zoomError) { setZoomError(false); } } function renderChart(data: HistogramData) { const xAxis = { type: 'category' as const, truncate: true, axisTick: { interval: 0, alignWithLabel: true, }, }; const colors = currentFilter === SpanOperationBreakdownFilter.None ? [...theme.charts.getColorPalette(1)] : [filterToColor(currentFilter)]; // Use a custom tooltip formatter as we need to replace // the tooltip content entirely when zooming is no longer available. const tooltip = { formatter(series) { const seriesData = Array.isArray(series) ? series : [series]; let contents: string[] = []; if (!zoomError) { // Replicate the necessary logic from sentry/components/charts/components/tooltip.jsx contents = seriesData.map(item => { const label = item.seriesName; const value = item.value[1].toLocaleString(); return [ '