Mixed chart doesn't support forced categorical x-axis
Bug description
For Mixed chart wasn't applied control that makes it possible to force numerical x-axes to categorical (https://github.com/apache/superset/pull/26404 was applied for bar and line charts.) When using mixed chart with bars face same problems:
- gaps between bars (pic.1)
- bar ovelap grid (pic.2)
- after applying cast to string for x-axes sorting is not working (pic.3)
How to reproduce the bug
- create mixed chart
- choose numeric column for x-axis
- query A - line type
- query B - bar type
Screenshots/recordings
pic.1
pic.2
pic.3
Superset version
master / latest-dev
Python version
3.9
Node version
16
Browser
Chrome
Additional context
Superset version 4.0.1
Checklist
- [X] I have searched Superset docs and Slack and didn't find a solution to my problem.
- [X] I have searched the GitHub issue tracker and didn't find a similar bug report.
- [ ] I have checked Superset's logs for errors and if I found a relevant Python stacktrace, I included it here as text in the "additional context" section.
Hey there, @propellerjet! I'm here to help you with any bugs, questions, or contributions you might have regarding the repository. Let's work together to resolve this issue.
The issue you're encountering with the mixed chart not supporting forced categorical x-axis has been addressed in a recent pull request. The xAxisForceCategorical control was introduced to handle this exact problem. This control allows numerical x-axes to be treated as categorical, which helps avoid gaps between bars, bar overlap with the grid, and sorting issues.
To enable this feature, ensure that the xAxisForceCategorical checkbox is checked in the chart controls. This will treat the numerical x-axis values as categorical, thereby resolving the issues mentioned.
Here is the relevant code snippet that defines the xAxisForceCategorical control:
export const xAxisForceCategoricalControl = {
name: 'xAxisForceCategorical',
config: {
type: 'CheckboxControl',
label: () => t('Force categorical'),
default: false,
description: t('Treat values as categorical.'),
initialValue: (control: ControlState, state: ControlPanelState | null) =>
state?.form_data?.x_axis_sort !== undefined || control.value,
renderTrigger: true,
visibility: ({ controls }: { controls: ControlStateMapping }) =>
checkColumnType(
getColumnLabel(controls?.x_axis?.value as QueryFormColumn),
controls?.datasource?.datasource,
[GenericDataType.Numeric],
),
shouldMapStateToProps: () => true,
},
};
In the transformProps function for the mixed timeseries chart, the xAxisType is determined based on the xAxisForceCategorical setting:
const xAxisType = getAxisType(stack, xAxisForceCategorical, xAxisDataType);
This ensures that the x-axis is treated as categorical when the xAxisForceCategorical control is enabled, thus avoiding gaps between bars, bar overlap with the grid, and sorting issues [1][2][3].
Additionally, there are specific tests related to the xAxisForceCategorical control in the Superset codebase, ensuring its functionality:
test('getAxisType without forced categorical', () => {
expect(getAxisType(false, false, GenericDataType.Temporal)).toEqual(
AxisType.Time,
);
expect(getAxisType(false, false, GenericDataType.Numeric)).toEqual(
AxisType.Value,
);
expect(getAxisType(true, false, GenericDataType.Numeric)).toEqual(
AxisType.Category,
);
expect(getAxisType(false, false, GenericDataType.Boolean)).toEqual(
AxisType.Category,
);
expect(getAxisType(false, false, GenericDataType.String)).toEqual(
AxisType.Category,
);
});
test('getAxisType with forced categorical', () => {
expect(getAxisType(false, true, GenericDataType.Numeric)).toEqual(
AxisType.Category,
);
});
To continue talking to Dosu, mention @dosu.
Any update this ? Would be great to have categorical mode for X-Axis on Mixed Chart when setting Bar mode
I think this was solved? I was able to creat Mixed Charts with categorical axes and bars, no problem. Happy to reopen this if I'm missing something.