Skip to content

Commit

Permalink
fix: Decimal values for Histogram bins (#32253)
Browse files Browse the repository at this point in the history
(cherry picked from commit ffe9244)
  • Loading branch information
michael-s-molina committed Feb 14, 2025
1 parent ed217ce commit c7cc436
Show file tree
Hide file tree
Showing 6 changed files with 112 additions and 37 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ export const titleControls: ControlPanelSectionConfig = {
type: 'SelectControl',
freeForm: true,
clearable: true,
label: t('X AXIS TITLE BOTTOM MARGIN'),
label: t('X Axis Title Margin'),
renderTrigger: true,
default: TITLE_MARGIN_OPTIONS[0],
choices: formatSelectOptions(TITLE_MARGIN_OPTIONS),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,9 @@ import {
formatSelectOptionsForRange,
dndGroupByControl,
columnsByType,
sections,
D3_FORMAT_OPTIONS,
D3_FORMAT_DOCS,
D3_NUMBER_FORMAT_DESCRIPTION_VALUES_TEXT,
} from '@superset-ui/chart-controls';
import { showLegendControl, showValueControl } from '../controls';

Expand Down Expand Up @@ -105,14 +107,65 @@ const config: ControlPanelConfig = {
],
],
},
sections.titleControls,
{
label: t('Chart Options'),
expanded: true,
controlSetRows: [
['color_scheme'],
[showValueControl],
[showLegendControl],
[
{
name: 'x_axis_title',
config: {
type: 'TextControl',
label: t('X Axis Title'),
renderTrigger: true,
default: '',
description: t('Changing this control takes effect instantly'),
},
},
],
[
{
name: 'x_axis_format',
config: {
type: 'SelectControl',
freeForm: true,
label: t('X Axis Format'),
renderTrigger: true,
default: 'SMART_NUMBER',
choices: D3_FORMAT_OPTIONS,
description: `${D3_FORMAT_DOCS} ${D3_NUMBER_FORMAT_DESCRIPTION_VALUES_TEXT}`,
},
},
],
[
{
name: 'y_axis_title',
config: {
type: 'TextControl',
label: t('Y Axis Title'),
renderTrigger: true,
default: '',
description: t('Changing this control takes effect instantly'),
},
},
],
[
{
name: 'y_axis_format',
config: {
type: 'SelectControl',
freeForm: true,
label: t('Y Axis Format'),
renderTrigger: true,
default: 'SMART_NUMBER',
choices: D3_FORMAT_OPTIONS,
description: `${D3_FORMAT_DOCS} ${D3_NUMBER_FORMAT_DESCRIPTION_VALUES_TEXT}`,
},
},
],
],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ import {
CategoricalColorNamespace,
NumberFormats,
getColumnLabel,
getNumberFormatter,
getValueFormatter,
tooltipHtml,
} from '@superset-ui/core';
import { HistogramChartProps, HistogramTransformedProps } from './types';
Expand All @@ -41,6 +41,7 @@ export default function transformProps(
const refs: Refs = {};
let focusedSeries: number | undefined;
const {
datasource: { currencyFormats = {}, columnFormats = {} },
formData,
height,
hooks,
Expand All @@ -58,19 +59,33 @@ export default function transformProps(
showLegend,
showValue,
sliceId,
xAxisFormat,
xAxisTitle,
yAxisTitle,
yAxisFormat,
} = formData;
const { data } = queriesData[0];
const colorFn = CategoricalColorNamespace.getScale(colorScheme);
const formatter = getNumberFormatter(
normalize ? NumberFormats.FLOAT_2_POINT : NumberFormats.INTEGER,
);

const formatter = (format: string) =>
getValueFormatter(
column,
currencyFormats,
columnFormats,
format,
undefined,
);
const xAxisFormatter = formatter(xAxisFormat);
const yAxisFormatter = formatter(yAxisFormat);

const percentFormatter = getPercentFormatter(NumberFormats.PERCENT_2_POINT);
const groupbySet = new Set(groupby);
const xAxisData: string[] = Object.keys(data[0]).filter(
key => !groupbySet.has(key),
);
const xAxisData: string[] = Object.keys(data[0])
.filter(key => !groupbySet.has(key))
.map(key => {
const array = key.split(' - ').map(value => parseFloat(value));
return `${xAxisFormatter(array[0])} '-' ${xAxisFormatter(array[1])}`;
});
const barSeries: BarSeriesOption[] = data.map(datum => {
const seriesName =
groupby.length > 0
Expand All @@ -91,7 +106,7 @@ export default function transformProps(
position: 'top',
formatter: params => {
const { value } = params;
return formatter.format(value as number);
return yAxisFormatter.format(value as number);
},
},
};
Expand All @@ -108,7 +123,7 @@ export default function transformProps(
const title = params[0].name;
const rows = params.map(param => {
const { marker, seriesName, value } = param;
return [`${marker}${seriesName}`, formatter.format(value as number)];
return [`${marker}${seriesName}`, yAxisFormatter.format(value as number)];
});
if (groupby.length > 0) {
const total = params.reduce(
Expand All @@ -122,7 +137,7 @@ export default function transformProps(
),
);
}
const totalRow = ['Total', formatter.format(total)];
const totalRow = ['Total', yAxisFormatter.format(total)];
if (!normalize) {
totalRow.push(percentFormatter.format(1));
}
Expand Down Expand Up @@ -159,7 +174,7 @@ export default function transformProps(
type: 'value',
nameLocation: 'middle',
axisLabel: {
formatter: (value: number) => formatter.format(value),
formatter: (value: number) => yAxisFormatter.format(value),
},
},
series: barSeries,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,9 @@ export type HistogramFormData = QueryFormData & {
sliceId: number;
showLegend: boolean;
showValue: boolean;
xAxisFormat: string;
xAxisTitle: string;
yAxisFormat: string;
yAxisTitle: string;
};

Expand Down
3 changes: 1 addition & 2 deletions superset/utils/pandas_postprocessing/histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,7 @@ def histogram(

# convert the bin edges to strings
bin_edges_str = [
f"{int(bin_edges[i])} - {int(bin_edges[i+1])}"
for i in range(len(bin_edges) - 1)
f"{bin_edges[i]} - {bin_edges[i+1]}" for i in range(len(bin_edges) - 1)
]

def hist_values(series: Series) -> np.ndarray:
Expand Down
48 changes: 27 additions & 21 deletions tests/unit_tests/pandas_postprocessing/test_histogram.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,13 @@ def test_histogram_no_groupby():
)
result = histogram(data_with_no_groupings, "a", [], bins)
assert result.shape == (1, bins)
assert result.columns.tolist() == ["1 - 2", "2 - 4", "4 - 6", "6 - 8", "8 - 10"]
assert result.columns.tolist() == [
"1.0 - 2.8",
"2.8 - 4.6",
"4.6 - 6.4",
"6.4 - 8.2",
"8.2 - 10.0",
]
assert result.values.tolist() == [[2, 2, 2, 2, 2]]


Expand All @@ -44,11 +50,11 @@ def test_histogram_with_groupby():
assert result.shape == (2, bins + 1)
assert result.columns.tolist() == [
"group",
"1 - 2",
"2 - 4",
"4 - 6",
"6 - 8",
"8 - 10",
"1.0 - 2.8",
"2.8 - 4.6",
"4.6 - 6.4",
"6.4 - 8.2",
"8.2 - 10.0",
]
assert result.values.tolist() == [["A", 2, 0, 2, 0, 2], ["B", 0, 2, 0, 2, 0]]

Expand All @@ -58,11 +64,11 @@ def test_histogram_with_groupby_and_normalize():
assert result.shape == (2, bins + 1)
assert result.columns.tolist() == [
"group",
"1 - 2",
"2 - 4",
"4 - 6",
"6 - 8",
"8 - 10",
"1.0 - 2.8",
"2.8 - 4.6",
"4.6 - 6.4",
"6.4 - 8.2",
"8.2 - 10.0",
]
assert result.values.tolist() == [
["A", 0.2, 0.0, 0.2, 0.0, 0.2],
Expand All @@ -75,11 +81,11 @@ def test_histogram_with_groupby_and_cumulative():
assert result.shape == (2, bins + 1)
assert result.columns.tolist() == [
"group",
"1 - 2",
"2 - 4",
"4 - 6",
"6 - 8",
"8 - 10",
"1.0 - 2.8",
"2.8 - 4.6",
"4.6 - 6.4",
"6.4 - 8.2",
"8.2 - 10.0",
]
assert result.values.tolist() == [["A", 2, 2, 4, 4, 6], ["B", 0, 2, 2, 4, 4]]

Expand All @@ -89,11 +95,11 @@ def test_histogram_with_groupby_and_cumulative_and_normalize():
assert result.shape == (2, bins + 1)
assert result.columns.tolist() == [
"group",
"1 - 2",
"2 - 4",
"4 - 6",
"6 - 8",
"8 - 10",
"1.0 - 2.8",
"2.8 - 4.6",
"4.6 - 6.4",
"6.4 - 8.2",
"8.2 - 10.0",
]
assert result.values.tolist() == [
[
Expand Down

0 comments on commit c7cc436

Please sign in to comment.