Split bar graph into two distinct horizontal and vertical bars (#15061)

### Summary

Split BAR into VERTICAL_BAR and HORIZONTAL_BAR as separate chart types.

### The Problem

Initially wanted a simple vertical/horizontal toggle for bar charts, but
ran into a GraphQL union type
constraint: union types can't have the same field name with different
nullability.

- Vertical bars need groupByFieldMetadataIdX as required (categories on
X)
- Horizontal bars need groupByFieldMetadataIdY as required (categories
on Y)
  - GraphQL schema generation fails with this setup

### The Solution

Use semantic primaryAxis and secondaryAxis naming that's
orientation-agnostic:

- primaryAxisGroupByFieldMetadataId = main grouping field (e.g.,
"Company Name")
- secondaryAxisGroupByFieldMetadataId = optional secondary grouping
(e.g., "Stage")

These fields have consistent meaning regardless of orientation. The
visual mapping happens at the UI layer:
  - Vertical bars: primary data renders on X-axis, secondary on Y-axis
  - Horizontal bars: primary data renders on Y-axis, secondary on X-axis

Both chart types share the same DTO structure with consistent
nullability.

### What Changed

  - Split GraphType.BAR → VERTICAL_BAR | HORIZONTAL_BAR
- Renamed fields: primaryAxisGroupByFieldMetadataId,
secondaryAxisGroupByFieldMetadataId (+ subfield
  variants)
- useChartSettingsValues(): Maps semantic fields to setting values (no
swapping)
- getBarChartSettings(): Dynamically arranges settings panel based on
orientation
- transformGroupByDataToBarChartData(): Maps semantic fields to Nivo's
layout prop
  
  video QA
  

https://github.com/user-attachments/assets/479061b5-712e-4ca6-9858-95273d1f16c1
This commit is contained in:
nitin
2025-10-15 15:08:48 +05:30
committed by GitHub
parent d21be90c5d
commit 436084f8f4
48 changed files with 1453 additions and 412 deletions
@@ -287,16 +287,16 @@ export type BarChartConfiguration = {
displayDataLabel?: Maybe<Scalars['Boolean']>;
filter?: Maybe<Scalars['JSON']>;
graphType: GraphType;
groupByFieldMetadataIdX: Scalars['UUID'];
groupByFieldMetadataIdY?: Maybe<Scalars['UUID']>;
groupBySubFieldNameX?: Maybe<Scalars['String']>;
groupBySubFieldNameY?: Maybe<Scalars['String']>;
groupMode?: Maybe<BarChartGroupMode>;
omitNullValues?: Maybe<Scalars['Boolean']>;
orderByX?: Maybe<GraphOrderBy>;
orderByY?: Maybe<GraphOrderBy>;
primaryAxisGroupByFieldMetadataId: Scalars['UUID'];
primaryAxisGroupBySubFieldName?: Maybe<Scalars['String']>;
primaryAxisOrderBy?: Maybe<GraphOrderBy>;
rangeMax?: Maybe<Scalars['Float']>;
rangeMin?: Maybe<Scalars['Float']>;
secondaryAxisGroupByFieldMetadataId?: Maybe<Scalars['UUID']>;
secondaryAxisGroupBySubFieldName?: Maybe<Scalars['String']>;
secondaryAxisOrderBy?: Maybe<GraphOrderBy>;
};
/** Display mode for bar charts with secondary grouping */
@@ -1448,11 +1448,12 @@ export enum GraphOrderBy {
/** Type of graph widget */
export enum GraphType {
BAR = 'BAR',
GAUGE = 'GAUGE',
HORIZONTAL_BAR = 'HORIZONTAL_BAR',
LINE = 'LINE',
NUMBER = 'NUMBER',
PIE = 'PIE'
PIE = 'PIE',
VERTICAL_BAR = 'VERTICAL_BAR'
}
export type GridPosition = {
@@ -1632,15 +1633,15 @@ export type LineChartConfiguration = {
displayDataLabel?: Maybe<Scalars['Boolean']>;
filter?: Maybe<Scalars['JSON']>;
graphType: GraphType;
groupByFieldMetadataIdX: Scalars['UUID'];
groupByFieldMetadataIdY?: Maybe<Scalars['UUID']>;
groupBySubFieldNameX?: Maybe<Scalars['String']>;
groupBySubFieldNameY?: Maybe<Scalars['String']>;
omitNullValues?: Maybe<Scalars['Boolean']>;
orderByX?: Maybe<GraphOrderBy>;
orderByY?: Maybe<GraphOrderBy>;
primaryAxisGroupByFieldMetadataId: Scalars['UUID'];
primaryAxisGroupBySubFieldName?: Maybe<Scalars['String']>;
primaryAxisOrderBy?: Maybe<GraphOrderBy>;
rangeMax?: Maybe<Scalars['Float']>;
rangeMin?: Maybe<Scalars['Float']>;
secondaryAxisGroupByFieldMetadataId?: Maybe<Scalars['UUID']>;
secondaryAxisGroupBySubFieldName?: Maybe<Scalars['String']>;
secondaryAxisOrderBy?: Maybe<GraphOrderBy>;
};
export type LinkMetadata = {