Skip to content

bar chart support#2005

Open
gingerwizard wants to merge 1 commit intohyperdxio:mainfrom
gingerwizard:bar_chart
Open

bar chart support#2005
gingerwizard wants to merge 1 commit intohyperdxio:mainfrom
gingerwizard:bar_chart

Conversation

@gingerwizard
Copy link
Copy Markdown
Contributor

Summary

This PR introduces Bar Charts. Historically, bar charts were effectively bar charts over time series. This implements true bar charts where the x-axis can be any grouping key.

As a result of this, line/bar charts are now called "Time Series"

Screenshots or video

image

How to test locally or on Vercel

  1. Navigate to Chart Explorer.
  2. Build a bar chart - Demo Traces - Group by ServiceName

@vercel
Copy link
Copy Markdown

vercel bot commented Mar 28, 2026

@gingerwizard is attempting to deploy a commit to the HyperDX Team on Vercel.

A member of the Team first needs to authorize it.

@changeset-bot
Copy link
Copy Markdown

changeset-bot bot commented Mar 28, 2026

⚠️ No Changeset found

Latest commit: 5d7cbe2

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@github-actions
Copy link
Copy Markdown
Contributor

PR Review

  • ⚠️ groupBy validation uses !form.groupBy which won't catch groupBy = [] (empty array is truthy in JS) → Change to !form.groupBy || (Array.isArray(form.groupBy) && form.groupBy.length === 0) in ChartEditor/utils.ts:260

  • ⚠️ formatResponseForPieChart reused for bar chart data in DBBarChart.tsx:185 → Shared usage is fine if the format is identical, but consider extracting to a shared formatCategoricalChartData utility to avoid confusion for future maintainers

  • ℹ️ BarChartTooltip memo component missing displayName → Add BarChartTooltip.displayName = 'BarChartTooltip' for better React DevTools experience (minor)

Overall the implementation is solid, follows existing patterns (mirrors DBPieChart closely), and the enum/validation/routing additions are correct. The operator precedence in the updated validateChartForm condition is fine — the parens correctly wrap all three display types.

Comment on lines +256 to +267
// Validate bar charts require a group by
if (
!isRawSqlChart &&
form.displayType === DisplayType.Bar &&
!form.groupBy
) {
errors.push({
path: `groupBy`,
message: 'Group By is required for bar charts',
});
}

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.

Could we add a unit test covering this check? There are existing unit tests covering this function which can be extended.

Comment on lines +29 to +31
> & {
maxNumberOfGroups?: number;
};
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.

Is this display setting intentionally not persisted? All other display settings are persisted as part of the config in the DB / URL Params and available via the API - it is odd if this one is not.

Perhaps instead of adding this new property, we can just use the existing limit property. That way it is persisted, and you don't have to copy back and forth between limit and maxNumberOfGroups in the places where that is happening right now.

normalizeChartConfig could also then be updated to strip limit from non-Bar type chart configs before saving, since the customizable limit is only available for bar charts (though it would be good to add to pie as well)

</>
)}

{isBarChart && (
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.

This is neat, and would be nice to add to Pie charts too.

However, we'd ideally give the user an Order By input as well, so that they can specify which 10 groups to show. There is an order by on the table chart type that might be re-usable

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.

We also should not show this for raw sql bar charts, since it's ignored.

);
};

export const DBBarChart = ({
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 run make ci-lint or make dev-lint and fix the formatting errors that are output.

numberFormat,
}: {
active?: boolean;
payload?: { name: string; value: number; payload: { color: string } }[];
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.

Suggested change
payload?: { name: string; value: number; payload: { color: string } }[];
payload?: { name: string; value: number; payload: { color: string, label: string } }[];

<ChartTooltipContainer>
<ChartTooltipItem
color={entry.payload.color}
name={entry.name}
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.

I'd recommend using the payload's name here so that the full label shows in the tooltip (since the full label is potentially shortened below the x-axis.

Image
Suggested change
name={entry.name}
name={entry.payload.name}

fillNulls,
compareToPreviousPeriod,
numberFormat,
maxNumberOfGroups: limit?.limit ?? 10,
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.

nit: It would be good to create an re-use a constant DEFAULT_MAX_GROUPS = 10 value here and elsewhere where 10 has been hardcoded.

export enum DisplayType {
Line = 'line',
StackedBar = 'stacked_bar',
Bar = 'bar',
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.

The external dashboards APIs need to be updated for this new type as well. You'll see related errors when running make ci-lint:

src/routers/external-api/v2/utils/dashboards.ts:159:24 - error TS1360: Type 'DisplayType.Bar | undefined' does not satisfy the expected type 'undefined'.
  Type 'DisplayType.Bar' is not assignable to type 'undefined'.

159     config.displayType satisfies never | undefined;
                           ~~~~~~~~~

src/routers/external-api/v2/utils/dashboards.ts:261:26 - error TS1360: Type 'DisplayType.Bar' does not satisfy the expected type 'never'.

261       config.displayType satisfies never;

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants