import { css } from '@emotion/css'; import { useState, type Dispatch, type SetStateAction } from 'react'; import { GrafanaTheme2 } from '@grafana/data'; import { useStyles2, useTheme2, Alert, Button } from '@grafana/ui'; import { t, Trans } from 'app/core/internationalization'; import { DataTrail } from '../DataTrail'; import { reportExploreMetrics } from '../interactions'; import { MetricSelectedEvent } from '../shared'; interface NativeHistogramInfoProps { histogramsLoaded: boolean; nativeHistograms: string[]; trail: DataTrail; } export function NativeHistogramBanner(props: NativeHistogramInfoProps) { const { histogramsLoaded, nativeHistograms, trail } = props; const [histogramMessage, setHistogramMessage] = useState(true); const [showHistogramExamples, setShowHistogramExamples] = useState(false); const styles = useStyles2(getStyles, 0); if (bannerHasBeenShown() || !histogramsLoaded || nativeHistograms.length === 0 || !histogramMessage) { return null; } return ( <> { { // when a user explicitly closes the banner, save that it has been closed in local storage to not show again setBannerHasBeenShown(); setHistogramMessage(false); }} className={styles.banner} >
Prometheus native histograms offer high resolution, high precision, simple usage in instrumentation and a way to combine and manipulate histograms in queries and in Grafana.
{showHistogramExamples && ( )}
} ); } interface NativeHistogramExamplesButtonProps { showHistogramExamples: boolean; setShowHistogramExamples: Dispatch>; } const NativeHistogramExamplesButton = ({ showHistogramExamples, setShowHistogramExamples, }: NativeHistogramExamplesButtonProps) => { const styles = useStyles2(getStyles, 0); return (
); }; type NativeHistogramExamplesProps = Pick & { setHistogramMessage: Dispatch>; }; const NativeHistogramExamples = ({ trail, nativeHistograms, setHistogramMessage }: NativeHistogramExamplesProps) => { const styles = useStyles2(getStyles, 0); const isDark = useTheme2().isDark; const selectNativeHistogram = (metric: string) => { reportExploreMetrics('native_histogram_example_clicked', { metric, }); trail.publishEvent(new MetricSelectedEvent(metric), true); }; const images = { nativeHeatmap: isDark ? 'public/img/native-histograms/DarkModeHeatmapNativeHistogram.png' : 'public/img/native-histograms/LightModeHeatmapNativeHistogram.png', classicHeatmap: isDark ? 'public/img/native-histograms/DarkModeHeatmapClassicHistogram.png' : 'public/img/native-histograms/LightModeHeatmapClassicHistogram.png', nativeHistogram: isDark ? 'public/img/native-histograms/DarkModeHistogramNativehistogram.png' : 'public/img/native-histograms/LightModeHistogramClassicHistogram.png', classicHistogram: isDark ? 'public/img/native-histograms/DarkModeHistogramClassicHistogram.png' : 'public/img/native-histograms/LightModeHistogramClassicHistogram.png', }; return ( <>
Now:
Previously:
Native Histogram displayed as heatmap:
Native Histogram displayed as heatmap
Native Histogram displayed as histogram:
Native Histogram displayed as histogram
Classic Histogram displayed as heatmap:
Classic Histogram displayed as heatmap
Classic Histogram displayed as histogram:
Classic Histogram displayed as histogram

Click any of the native histograms below to explore them:
{nativeHistograms.map((el) => { return (
); })}
); }; function getStyles(theme: GrafanaTheme2, _chromeHeaderHeight: number) { return { banner: css({ flexGrow: 0, }), histogramRow: css({ display: 'flex', flexDirection: 'row', gap: theme.spacing(2), }), histogramSentence: css({ width: '90%', }), histogramLearnMore: css({ width: '10%', }), button: css({ float: 'right', }), seeExamplesButton: css({ paddingLeft: '0px', }), seeExamplesRow: css({ paddingTop: '4px', }), histogramImageCol: css({ display: 'flex', flexDirection: 'column', flexBasis: '100%', flex: '1', }), fontSmall: css({ fontSize: theme.typography.size.sm, }), imageText: css({ paddingBottom: '4px', }), rightImageCol: css({ borderLeft: `1px solid ${theme.colors.secondary.borderTransparent}`, }), rightCol: css({ paddingLeft: '16px', }), }; } export function setBannerHasBeenShown() { localStorage.setItem('nativeHistogramBanner', 'true'); } export function bannerHasBeenShown() { return localStorage.getItem('nativeHistogramBanner') ?? false; }