Skip to content
Open
Show file tree
Hide file tree
Changes from 23 commits
Commits
Show all changes
24 commits
Select commit Hold shift + click to select a range
ec48095
feat: wire heatmap chart into dashboard editor and rendering
cursoragent Apr 11, 2026
1ee7f0f
feat: auto-populate duration defaults for trace sources, pass numberF…
cursoragent Apr 11, 2026
21dfd1a
fix: add tableSource to useEffect dependency array
cursoragent Apr 11, 2026
f21af1f
feat: auto-populate heatmap defaults on source change, disable intera…
cursoragent Apr 11, 2026
9a15708
feat: fill Value/Count fields with actual defaults, add Display Setti…
cursoragent Apr 11, 2026
58011b3
refactor: unify Heatmap Settings across search, chart editor, and das…
cursoragent Apr 11, 2026
a7d7646
fix: reduce uPlot top padding, prevent drawer scroll lock, restore Ch…
cursoragent Apr 13, 2026
aa64f1a
fix: prevent layout shift by portaling HeatmapSettingsDrawer, revert …
cursoragent Apr 13, 2026
1f5b425
fix: auto-run chart preview when editing dashboard tiles
cursoragent Apr 13, 2026
09854eb
rename: Heatmap Settings → Display Settings for consistency
cursoragent Apr 13, 2026
9b4dc70
fix: lift HeatmapSettingsDrawer to EditTimeChartForm level to prevent…
cursoragent Apr 13, 2026
1895cee
refactor: address code review — extract toHeatmapChartConfig, fix sta…
cursoragent Apr 13, 2026
0160d84
merge: resolve conflict with main (raw SQL alert validation)
cursoragent Apr 13, 2026
af06542
fix: remove unused HeatmapSelectExtras export, memoize defaultValues
cursoragent Apr 13, 2026
b392516
fix: widen Y-axis and add right padding to prevent label clipping
cursoragent Apr 13, 2026
78c26de
fix: dynamic Y-axis sizing and compact tick labels
cursoragent Apr 13, 2026
d68bb1a
fix: prettier formatting in formatDurationMsCompact
cursoragent Apr 13, 2026
9772d1f
fix: X-axis label overlap, replace IIFEs with components
cursoragent Apr 13, 2026
2721fb6
fix: increase X-axis min tick spacing to prevent cramped labels in sm…
cursoragent Apr 13, 2026
badd8d5
fix: add 4px left padding to prevent Y-axis label clipping
cursoragent Apr 13, 2026
58fd368
fix: add left padding to search heatmap container to prevent Y-axis c…
cursoragent Apr 14, 2026
7180587
fix: add right padding to search heatmap container to match left
cursoragent Apr 14, 2026
59b2476
fix: hide Generated SQL for heatmap, clean up useEffect deps
cursoragent Apr 14, 2026
a587ca2
fix: restrict heatmap data source picker to trace sources only
alex-fedotyev Apr 15, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 40 additions & 0 deletions packages/app/src/DBDashboardPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
} from '@hyperdx/common-utils/dist/guards';
import {
AlertState,
BuilderChartConfigWithDateRange,
ChartConfigWithDateRange,
DashboardContainer,
DashboardFilter,
Expand Down Expand Up @@ -101,6 +102,9 @@ import {
} from '@/dashboard';

import ChartContainer from './components/charts/ChartContainer';
import DBHeatmapChart, {
toHeatmapChartConfig,
} from './components/DBHeatmapChart';
import { DBPieChart } from './components/DBPieChart';
import DBSqlRowTableWithSideBar from './components/DBSqlRowTableWithSidebar';
import OnboardingModal from './components/OnboardingModal';
Expand Down Expand Up @@ -135,6 +139,31 @@ import { useZIndex, ZIndexContext } from './zIndex';
import 'react-grid-layout/css/styles.css';
import 'react-resizable/css/styles.css';

function HeatmapTile({
keyPrefix,
chartId,
title,
toolbar,
queriedConfig,
}: {
keyPrefix: string;
chartId: string;
title: React.ReactNode;
toolbar: React.ReactNode[];
queriedConfig: BuilderChartConfigWithDateRange;
}) {
const { heatmapConfig, scaleType } = toHeatmapChartConfig(queriedConfig);
return (
<DBHeatmapChart
key={`${keyPrefix}-${chartId}`}
title={title}
toolbarPrefix={toolbar}
config={heatmapConfig}
scaleType={scaleType}
/>
);
}

const makeId = () => Math.floor(100000000 * Math.random()).toString(36);

const ReactGridLayout = WidthProvider(RGL);
Expand Down Expand Up @@ -599,6 +628,16 @@ const Tile = forwardRef(
config={queriedConfig}
/>
)}
{queriedConfig?.displayType === DisplayType.Heatmap &&
isBuilderChartConfig(queriedConfig) && (
<HeatmapTile
keyPrefix={keyPrefix}
chartId={chart.id}
title={title}
toolbar={toolbar}
queriedConfig={queriedConfig}
/>
)}
{effectiveMarkdownConfig?.displayType ===
DisplayType.Markdown &&
'markdown' in effectiveMarkdownConfig && (
Expand Down Expand Up @@ -789,6 +828,7 @@ const EditTileModal = ({
onClose={handleClose}
onDirtyChange={setHasUnsavedChanges}
isDashboardForm
autoRun
/>
</ZIndexContext.Provider>
)}
Expand Down
19 changes: 17 additions & 2 deletions packages/app/src/components/ChartEditor/utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -266,12 +266,13 @@ export const validateChartForm = (
}
}

// Validate number and pie charts only have one series
// Validate number, pie, and heatmap charts only have one series
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please update the unit tests to cover the changes in this file

if (
!isRawSqlChart &&
Array.isArray(form.series) &&
(form.displayType === DisplayType.Number ||
form.displayType === DisplayType.Pie) &&
form.displayType === DisplayType.Pie ||
form.displayType === DisplayType.Heatmap) &&
form.series.length > 1
) {
errors.push({
Expand All @@ -280,6 +281,20 @@ export const validateChartForm = (
});
}

// Validate heatmap requires a value expression
if (
!isRawSqlChart &&
form.displayType === DisplayType.Heatmap &&
Array.isArray(form.series) &&
form.series.length > 0 &&
!form.series[0]?.valueExpression
) {
errors.push({
path: `series.0.valueExpression`,
message: 'Value expression is required for heatmap charts',
});
}

for (const error of errors) {
console.warn(`Validation error in field ${error.path}: ${error.message}`);
setError(error.path, {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import { IS_LOCAL_MODE } from '@/config';
import { DEFAULT_TILE_ALERT } from '@/utils/alerts';

import { ChartSeriesEditor } from './ChartSeriesEditor';
import { HeatmapSeriesEditor } from './HeatmapSeriesEditor';
import { TileAlertEditor } from './TileAlertEditor';

type ChartEditorControlsProps = {
Expand Down Expand Up @@ -56,6 +57,7 @@ type ChartEditorControlsProps = {
chartConfigForExplanations?: ChartConfigWithOptTimestamp;
onSubmit: (suppressErrorNotification?: boolean) => void;
openDisplaySettings: () => void;
openHeatmapSettings?: () => void;
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does this need to be optional? Looks like it is always provided

Suggested change
openHeatmapSettings?: () => void;
openHeatmapSettings: () => void;

};

export function ChartEditorControls({
Expand Down Expand Up @@ -83,6 +85,7 @@ export function ChartEditorControls({
chartConfigForExplanations,
onSubmit,
openDisplaySettings,
openHeatmapSettings,
}: ChartEditorControlsProps) {
return (
<>
Expand Down Expand Up @@ -113,7 +116,15 @@ export function ChartEditorControls({
)}
</Group>
</Flex>
{displayType !== DisplayType.Search && Array.isArray(select) ? (
{displayType === DisplayType.Heatmap && Array.isArray(select) ? (
<HeatmapSeriesEditor
control={control}
setValue={setValue}
tableSource={tableSource}
onSubmit={onSubmit}
onOpenDisplaySettings={openHeatmapSettings ?? openDisplaySettings}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would we ever want to open the display settings here?

Suggested change
onOpenDisplaySettings={openHeatmapSettings ?? openDisplaySettings}
onOpenHeatmapSettings={openHeatmapSettings}

/>
) : displayType !== DisplayType.Search && Array.isArray(select) ? (
<>
{fields.map((field, index) => (
<ChartSeriesEditor
Expand Down Expand Up @@ -208,7 +219,8 @@ export function ChartEditorControls({
<Flex mt={4} align="center" justify="space-between">
<Group gap="xs">
{displayType !== DisplayType.Number &&
displayType !== DisplayType.Pie && (
displayType !== DisplayType.Pie &&
displayType !== DisplayType.Heatmap && (
<Button
variant="subtle"
size="sm"
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
import { useCallback, useMemo, useState } from 'react';
import { isBuilderChartConfig } from '@hyperdx/common-utils/dist/guards';
import {
BuilderChartConfigWithDateRange,
ChartConfigWithDateRange,
ChartConfigWithOptTimestamp,
DisplayType,
SourceKind,
TSource,
} from '@hyperdx/common-utils/dist/types';
Expand All @@ -14,6 +16,9 @@ import { buildTableRowSearchUrl } from '@/ChartUtils';
import { getAlertReferenceLines } from '@/components/Alerts';
import { ChartEditorFormState } from '@/components/ChartEditor/types';
import ChartSQLPreview from '@/components/ChartSQLPreview';
import DBHeatmapChart, {
toHeatmapChartConfig,
} from '@/components/DBHeatmapChart';
import DBNumberChart from '@/components/DBNumberChart';
import { DBPieChart } from '@/components/DBPieChart';
import DBSqlRowTableWithSideBar from '@/components/DBSqlRowTableWithSidebar';
Expand All @@ -28,6 +33,19 @@ import {

import { buildSampleEventsConfig, isQueryReady } from './utils';

function HeatmapPreview({
config,
}: {
config: BuilderChartConfigWithDateRange;
}) {
const { heatmapConfig, scaleType } = toHeatmapChartConfig(config);
return (
<div className="flex-grow-1 d-flex flex-column" style={{ height: 400 }}>
<DBHeatmapChart config={heatmapConfig} scaleType={scaleType} />
</div>
);
}

type ChartPreviewPanelProps = {
queriedConfig?: ChartConfigWithDateRange;
tableSource?: TSource;
Expand Down Expand Up @@ -159,6 +177,10 @@ export function ChartPreviewPanel({
/>
</div>
)}
{queryReady &&
queriedConfig != null &&
isBuilderChartConfig(queriedConfig) &&
activeTab === 'heatmap' && <HeatmapPreview config={queriedConfig} />}
{queryReady &&
tableSource &&
queriedConfig != null &&
Expand Down
Loading
Loading