feat(explore): Add Heat Map widget to Explore metrics#115608
Conversation
Adds a Heat Map visualization option to the Explore metrics tab, gated behind the `organizations:data-browsing-heat-map-widget` feature flag. - Add `ChartType.HEATMAP` to the chart type enum - Create `MetricsHeatMap` component using the existing `HeatMapWidgetVisualization` from dashboards widgets - Create `metricHeatmapApiOptions` for fetching heatmap data from the `/events-heatmap/` endpoint - Extract shared chart actions (type selector, interval) to `MetricPanel` so both `MetricsGraph` and `MetricsHeatMap` can use them - Disable aggregate and group-by dropdowns when heatmap is selected via `disabledReason` prop pattern - Filter heatmaps from dashboard widget export - Extract graph height constants to `settings.ts` Ref: DAIN-1635
The wrapping Tooltip component broke flex layout, causing the disabled aggregate and group-by dropdowns to not stretch correctly. Use tooltipProps on the OverlayTrigger.Button instead, matching the pattern used by DeleteMetricButton.
…sions Use useDimensions to measure the chart container width, then derive yBuckets from the aspect ratio so heatmap cells are roughly square instead of rectangular.
The heatmap API returns generic types for the value field. Use the trace metric's known unit to patch the Y-axis meta so the visualization formats axis labels with the correct unit (e.g. "1.5 KB" not "1500").
|
@cursor review |
…-1635-add-heat-map-widget-to-explore-ii ; Conflicts: ; knip.config.ts
📊 Type Coverage Diff
🔍 1 new type safety issue introducedType assertions (
This is informational only and does not block the PR. |
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 2 potential issues.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 206c7ee. Configure here.
| isPending || !heatMapSeries ? ( | ||
| <WidgetLoadingPanel /> | ||
| ) : error ? ( | ||
| <Widget.WidgetError error={error} /> |
There was a problem hiding this comment.
Error state hidden behind loading check in heatmap
Medium Severity
When the heatmap API request fails, data (heatMapSeries) is undefined and isPending is false. The condition isPending || !heatMapSeries evaluates to true because !heatMapSeries is true, so WidgetLoadingPanel is rendered instead of Widget.WidgetError. The error branch is unreachable on initial load failures, leaving users stuck on an infinite loading spinner instead of seeing the error message.
Reviewed by Cursor Bugbot for commit 206c7ee. Configure here.
| import { | ||
| MINIMIZED_GRAPH_HEIGHT, | ||
| STACKED_GRAPH_HEIGHT, | ||
| } from 'sentry/views/explore/metrics/settings'; |
There was a problem hiding this comment.
Import statement placed after function definition
Low Severity
The import of MINIMIZED_GRAPH_HEIGHT and STACKED_GRAPH_HEIGHT from the settings file is placed after the getMetricsChartTypeOptions function definition at line 49. While ES module imports are hoisted so this won't cause a runtime error, it's clearly an accidental artifact of the refactor that moved these constants out to a separate file.
Reviewed by Cursor Bugbot for commit 206c7ee. Configure here.


e.g.,
Heat Map support for Metrics! This version is fairly light on crimes, but heavy on shenanigans to be addressed as the project continues.
Here's the gist
valueon the Y-axis andcount()on the Z-axis (for now)The gist of the PR is:
MetricPanelis in charge of data loading. For heat maps, it makes a request to another endpoint altogether, and returns the dataMetricGraphhas a sibling calledMetricHeatMap. In order to share code between them, they both acceptActionsas a prop from the parent, so they get the same buttons for chart type and interval without having to copy stuff. So, that code lives inMetricPanelnow