fix(charts): add X Axis Number Format control for numeric X-axis columns (#38809)

Co-authored-by: codeant-ai-for-open-source[bot] <244253245+codeant-ai-for-open-source[bot]@users.noreply.github.com>
This commit is contained in:
Enzo Martellucci
2026-03-31 12:38:07 +02:00
committed by GitHub
parent 2c9cf0bd55
commit e0a0a22542
16 changed files with 865 additions and 106 deletions

View File

@@ -17,7 +17,10 @@
* under the License.
*/
import { t } from '@apache-superset/core/translation';
import { getColumnLabel, QueryFormColumn } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/common';
import {
checkColumnType,
ControlPanelConfig,
ControlPanelsContainerProps,
ControlSubSectionHeader,
@@ -181,6 +184,30 @@ const config: ControlPanelConfig = {
...sharedControls.x_axis_time_format,
default: 'smart_date',
description: `${D3_TIME_FORMAT_DOCS}. ${TIME_SERIES_DESCRIPTION_TEXT}`,
visibility: ({ controls }: ControlPanelsContainerProps) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Temporal],
),
disableStash: true,
resetOnHide: false,
},
},
],
[
{
name: 'x_axis_number_format',
config: {
...sharedControls.x_axis_number_format,
default: '~g',
mapStateToProps: undefined,
visibility: ({ controls }: ControlPanelsContainerProps) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Numeric],
),
},
},
],

View File

@@ -17,8 +17,15 @@
* under the License.
*/
import { t } from '@apache-superset/core/translation';
import { ensureIsArray, JsonArray } from '@superset-ui/core';
import {
ensureIsArray,
getColumnLabel,
JsonArray,
QueryFormColumn,
} from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/common';
import {
checkColumnType,
ControlPanelConfig,
ControlPanelsContainerProps,
ControlSetRow,
@@ -154,6 +161,13 @@ function createAxisControl(axis: 'x' | 'y'): ControlSetRow[] {
Boolean(controls?.orientation.value === OrientationType.Vertical);
const isHorizontal = (controls: ControlStateMapping) =>
Boolean(controls?.orientation.value === OrientationType.Horizontal);
const isNumericXAxis = (controls: ControlStateMapping) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Numeric],
);
return [
[
{
@@ -163,7 +177,23 @@ function createAxisControl(axis: 'x' | 'y'): ControlSetRow[] {
default: 'smart_date',
description: `${D3_TIME_FORMAT_DOCS}. ${TIME_SERIES_DESCRIPTION_TEXT}`,
visibility: ({ controls }: ControlPanelsContainerProps) =>
isXAxis ? isVertical(controls) : isHorizontal(controls),
(isXAxis ? isVertical(controls) : isHorizontal(controls)) &&
!isNumericXAxis(controls),
disableStash: true,
resetOnHide: false,
},
},
],
[
{
name: 'x_axis_number_format',
config: {
...sharedControls.x_axis_number_format,
default: '~g',
mapStateToProps: undefined,
visibility: ({ controls }: ControlPanelsContainerProps) =>
(isXAxis ? isVertical(controls) : isHorizontal(controls)) &&
isNumericXAxis(controls),
disableStash: true,
resetOnHide: false,
},

View File

@@ -17,7 +17,10 @@
* under the License.
*/
import { t } from '@apache-superset/core/translation';
import { getColumnLabel, QueryFormColumn } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/common';
import {
checkColumnType,
ControlPanelConfig,
ControlPanelsContainerProps,
ControlSubSectionHeader,
@@ -146,6 +149,30 @@ const config: ControlPanelConfig = {
...sharedControls.x_axis_time_format,
default: 'smart_date',
description: `${D3_TIME_FORMAT_DOCS}. ${TIME_SERIES_DESCRIPTION_TEXT}`,
visibility: ({ controls }: ControlPanelsContainerProps) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Temporal],
),
disableStash: true,
resetOnHide: false,
},
},
],
[
{
name: 'x_axis_number_format',
config: {
...sharedControls.x_axis_number_format,
default: '~g',
mapStateToProps: undefined,
visibility: ({ controls }: ControlPanelsContainerProps) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Numeric],
),
},
},
],

View File

@@ -17,7 +17,10 @@
* under the License.
*/
import { t } from '@apache-superset/core/translation';
import { getColumnLabel, QueryFormColumn } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/common';
import {
checkColumnType,
ControlPanelConfig,
ControlPanelsContainerProps,
ControlSubSectionHeader,
@@ -112,53 +115,28 @@ const config: ControlPanelConfig = {
...sharedControls.x_axis_time_format,
default: 'smart_date',
description: `${D3_TIME_FORMAT_DOCS}. ${TIME_SERIES_DESCRIPTION_TEXT}`,
visibility: ({ controls }: ControlPanelsContainerProps) => {
// check if x axis is a time column
const xAxisColumn = controls?.x_axis?.value;
const xAxisOptions = controls?.x_axis?.options;
if (!xAxisColumn || !Array.isArray(xAxisOptions)) {
return false;
}
const xAxisType = xAxisOptions.find(
option => option.column_name === xAxisColumn,
)?.type;
return (
typeof xAxisType === 'string' &&
xAxisType.toUpperCase().includes('TIME')
);
},
visibility: ({ controls }: ControlPanelsContainerProps) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Temporal],
),
disableStash: true,
resetOnHide: false,
},
},
{
name: 'x_axis_number_format',
config: {
...sharedControls.x_axis_number_format,
visibility: ({ controls }: ControlPanelsContainerProps) => {
// check if x axis is a floating-point column
const xAxisColumn = controls?.x_axis?.value;
const xAxisOptions = controls?.x_axis?.options;
if (!xAxisColumn || !Array.isArray(xAxisOptions)) {
return false;
}
const xAxisType = xAxisOptions.find(
option => option.column_name === xAxisColumn,
)?.type;
if (typeof xAxisType !== 'string') {
return false;
}
const typeUpper = xAxisType.toUpperCase();
return ['FLOAT', 'DOUBLE', 'REAL', 'NUMERIC', 'DECIMAL'].some(
t => typeUpper.includes(t),
);
},
default: '~g',
mapStateToProps: undefined,
visibility: ({ controls }: ControlPanelsContainerProps) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Numeric],
),
},
},
],

View File

@@ -17,7 +17,10 @@
* under the License.
*/
import { t } from '@apache-superset/core/translation';
import { getColumnLabel, QueryFormColumn } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/common';
import {
checkColumnType,
ControlPanelConfig,
ControlPanelsContainerProps,
ControlSubSectionHeader,
@@ -111,6 +114,30 @@ const config: ControlPanelConfig = {
...sharedControls.x_axis_time_format,
default: 'smart_date',
description: `${D3_TIME_FORMAT_DOCS}. ${TIME_SERIES_DESCRIPTION_TEXT}`,
visibility: ({ controls }: ControlPanelsContainerProps) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Temporal],
),
disableStash: true,
resetOnHide: false,
},
},
],
[
{
name: 'x_axis_number_format',
config: {
...sharedControls.x_axis_number_format,
default: '~g',
mapStateToProps: undefined,
visibility: ({ controls }: ControlPanelsContainerProps) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Numeric],
),
},
},
],

View File

@@ -17,7 +17,10 @@
* under the License.
*/
import { t } from '@apache-superset/core/translation';
import { getColumnLabel, QueryFormColumn } from '@superset-ui/core';
import { GenericDataType } from '@apache-superset/core/common';
import {
checkColumnType,
ControlPanelConfig,
ControlPanelsContainerProps,
ControlSubSectionHeader,
@@ -163,6 +166,30 @@ const config: ControlPanelConfig = {
...sharedControls.x_axis_time_format,
default: 'smart_date',
description: `${D3_TIME_FORMAT_DOCS}. ${TIME_SERIES_DESCRIPTION_TEXT}`,
visibility: ({ controls }: ControlPanelsContainerProps) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Temporal],
),
disableStash: true,
resetOnHide: false,
},
},
],
[
{
name: 'x_axis_number_format',
config: {
...sharedControls.x_axis_number_format,
default: '~g',
mapStateToProps: undefined,
visibility: ({ controls }: ControlPanelsContainerProps) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Numeric],
),
},
},
],