Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,16 @@ describe('BigNumber Total Control Panel Config', () => {
row.some((control: any) => control.name === 'conditional_formatting'),
);
expect(conditionalFormattingRow).toBeTruthy();

// Check header_alignment control exists in one of the rows
const headerAlignmentRow = thirdSection.find(row =>
row.some((control: any) => control.name === 'header_alignment'),
);
expect(headerAlignmentRow).toBeTruthy();
expect(headerAlignmentRow![0]).toMatchObject({
name: 'header_alignment',
config: expect.objectContaining({ default: 'left' }),
});
});

test('should have y_axis_format override with correct label', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
subtitleControl,
showMetricNameControl,
metricNameFontSizeWithVisibility,
headerAlignmentControl,
} from '../sharedControls';

export default {
Expand Down Expand Up @@ -124,6 +125,7 @@ export default {
},
},
],
[headerAlignmentControl],
],
},
],
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ describe('BigNumberTotal transformProps', () => {
yAxisFormat: 'SMART_NUMBER',
conditionalFormatting: [{ color: 'red', op: '>', value: 0 }],
currencyFormat: { symbol: '$', symbolPosition: 'prefix' },
headerAlignment: 'center',
};

const baseDatasource = {
Expand Down Expand Up @@ -86,6 +87,7 @@ describe('BigNumberTotal transformProps', () => {
expect(result.subtitle).toBe(baseFormData.subheader);
expect(result.onContextMenu).toBe(onContextMenu);
expect(result.refs).toEqual({});
expect(result.headerAlignment).toBe('center');
// headerFormatter should be set even if there's no data
expect(typeof result.headerFormatter).toBe('function');
// colorThresholdFormatters fallback to empty array when getColorFormatters returns falsy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ export default function transformProps(
currencyFormat,
subheader,
subheaderFontSize,
headerAlignment,
} = formData;
const refs: Refs = {};
const {
Expand Down Expand Up @@ -143,5 +144,6 @@ export default function transformProps(
metricName: originalLabel,
showMetricName,
metricNameFontSize,
headerAlignment,
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,15 @@ import {
getNumberFormatter,
TimeFormatter,
} from '@superset-ui/core';
import { render, fireEvent } from '../../../../spec/helpers/testing-library';
import {
render,
fireEvent,
waitFor,
} from '../../../../spec/helpers/testing-library';
import BigNumberVis from './BigNumberViz';
import Echart from '../components/Echart';
import { EventHandlers } from '../types';
import { BigNumberWithTrendlineFormData } from './types';
import { BigNumberWithTrendlineFormData, HeaderAlignment } from './types';

jest.mock('../components/Echart', () => ({
__esModule: true,
Expand Down Expand Up @@ -303,3 +307,147 @@ describe('BigNumberViz trendline and subheader rendering', () => {
expect(container.querySelector('.subheader-line')).not.toBeInTheDocument();
});
});

describe('BigNumberViz alignment', () => {
const renderViz = (headerAlignment?: HeaderAlignment) =>
render(
<BigNumberVis
width={200}
height={100}
bigNumber={42}
headerFormatter={getNumberFormatter()}
headerFontSize={0.3}
subheaderFontSize={0.125}
subtitleFontSize={0.125}
subtitle=""
refs={{}}
headerAlignment={headerAlignment}
Comment thread
rusackas marked this conversation as resolved.
/>,
).container;

test('defaults to left alignment', () => {
const container = renderViz();

const textContainer = container.querySelector('.text-container');
expect(container.firstElementChild).toHaveStyle({
alignItems: 'flex-start',
});
expect(textContainer).toHaveStyle({ alignItems: 'flex-start' });
const headerLine = container.querySelector('.header-line');
expect(headerLine).toHaveStyle({ justifyContent: 'flex-start' });
});

test('centers content when headerAlignment is "center"', () => {
const container = renderViz('center');

const textContainer = container.querySelector('.text-container');
Comment thread
rusackas marked this conversation as resolved.
expect(container.firstElementChild).toHaveStyle({ alignItems: 'center' });
expect(textContainer).toHaveStyle({ alignItems: 'center' });
const headerLine = container.querySelector('.header-line');
expect(headerLine).toHaveStyle({ justifyContent: 'center' });
});

test('right-aligns content when headerAlignment is "right"', () => {
const container = renderViz('right');

const textContainer = container.querySelector('.text-container');
expect(container.firstElementChild).toHaveStyle({ alignItems: 'flex-end' });
expect(textContainer).toHaveStyle({ alignItems: 'flex-end' });
const headerLine = container.querySelector('.header-line');
expect(headerLine).toHaveStyle({ justifyContent: 'flex-end' });
});

test.each([
['center', 'center'],
['right', 'flex-end'],
] as const)(
'aligns the outer chart and text container for "%s" with a trendline',
(headerAlignment, alignItems) => {
const { container } = render(
<BigNumberVis
width={200}
height={100}
bigNumber={42}
headerFormatter={getNumberFormatter()}
headerFontSize={0.3}
subheaderFontSize={0.125}
subtitleFontSize={0.125}
subheader="subheader text"
subtitle=""
refs={{}}
headerAlignment={headerAlignment}
showTrendLine
trendLineData={[
[1577836800000, 10],
[1577923200000, 20],
]}
echartOptions={{}}
/>,
);

expect(container.firstElementChild).toHaveStyle({ alignItems });
expect(container.querySelector('.text-container')).toHaveStyle({
alignItems,
});
},
);

test('keeps the value and subheader centered when the trendline layout overflows', async () => {
const offsetHeightDescriptor = Object.getOwnPropertyDescriptor(
HTMLElement.prototype,
'offsetHeight',
);
// Force shouldApplyOverflow to report an overflow, which switches
// .text-container from a flex to a block container.
Object.defineProperty(HTMLElement.prototype, 'offsetHeight', {
configurable: true,
get: () => 1000,
});

try {
const { container } = render(
<BigNumberVis
width={200}
height={100}
bigNumber={42}
headerFormatter={getNumberFormatter()}
headerFontSize={0.3}
subheaderFontSize={0.125}
subtitleFontSize={0.125}
subheader="subheader text"
subtitle=""
refs={{}}
headerAlignment="center"
showTrendLine
trendLineData={[
[1577836800000, 10],
[1577923200000, 20],
]}
echartOptions={{}}
/>,
);

await waitFor(() => {
expect(container.querySelector('.text-container')).toHaveStyle({
display: 'block',
});
});

const headerLine = container.querySelector('.header-line');
expect(headerLine).toHaveStyle({ justifyContent: 'center' });
const subheaderLine = container.querySelector('.subheader-line');
expect(subheaderLine).toHaveStyle({ textAlign: 'center' });
} finally {
if (offsetHeightDescriptor) {
Object.defineProperty(
HTMLElement.prototype,
'offsetHeight',
offsetHeightDescriptor,
);
} else {
delete (HTMLElement.prototype as { offsetHeight?: number })
.offsetHeight;
}
}
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -28,12 +28,18 @@ import {
} from '@superset-ui/core';
import { styled, useTheme } from '@apache-superset/core/theme';
import Echart from '../components/Echart';
import { BigNumberVizProps } from './types';
import { BigNumberVizProps, HeaderAlignment } from './types';
import { PROPORTION } from './constants';
import { EventHandlers } from '../types';

const defaultNumberFormatter = getNumberFormatter();

const ALIGN_ITEMS: Record<HeaderAlignment, string> = {
left: 'flex-start',
center: 'center',
right: 'flex-end',
};

function BigNumberVis({
className = '',
headerFormatter = defaultNumberFormatter,
Expand All @@ -47,9 +53,11 @@ function BigNumberVis({
subheader = '',
subheaderFontSize = PROPORTION.SUBHEADER,
subtitleFontSize = PROPORTION.SUBHEADER,
headerAlignment = 'left',
...props
}: BigNumberVizProps) {
const theme = useTheme();
const alignItems = ALIGN_ITEMS[headerAlignment];

// Convert state to hooks
const [elementsRendered, setElementsRendered] = useState(false);
Expand Down Expand Up @@ -132,6 +140,7 @@ function BigNumberVis({
style={{
fontSize,
height: 'auto',
textAlign: headerAlignment,
}}
>
{text}
Expand Down Expand Up @@ -170,6 +179,7 @@ function BigNumberVis({
style={{
fontSize,
height: 'auto',
textAlign: headerAlignment,
}}
>
{text}
Expand Down Expand Up @@ -236,6 +246,9 @@ function BigNumberVis({
style={{
display: 'flex',
alignItems: 'center',
// header-line is always a flex container, so text-align has no
// effect on the number's position; justify-content does.
justifyContent: alignItems,
fontSize,
height: 'auto',
color: numberColor,
Expand Down Expand Up @@ -275,6 +288,7 @@ function BigNumberVis({
style={{
fontSize,
height: maxHeight,
textAlign: headerAlignment,
}}
>
{text}
Expand Down Expand Up @@ -321,6 +335,7 @@ function BigNumberVis({
style={{
fontSize: `${fontSize}px`,
height: maxHeight,
textAlign: headerAlignment,
}}
>
{text}
Expand Down Expand Up @@ -425,11 +440,12 @@ function BigNumberVis({
const overflow = shouldApplyOverflow(allTextHeight);

return (
<div className={componentClassName}>
<div className={componentClassName} style={{ alignItems }}>
<div
className="text-container"
style={{
height: allTextHeight,
alignItems,
...(overflow
? {
display: 'block',
Expand Down Expand Up @@ -472,6 +488,7 @@ function BigNumberVis({
className={componentClassName}
style={{
height,
alignItems,
...(overflow
? {
display: 'block',
Expand All @@ -483,7 +500,7 @@ function BigNumberVis({
: {}),
}}
>
<div className="text-container">
<div className="text-container" style={{ alignItems }}>
{renderFallbackWarning()}
{renderMetricName((metricNameFontSize || 0) * height)}
{renderKicker((kickerFontSize || 0) * height)}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ import {
subtitleControl,
showMetricNameControl,
metricNameFontSizeWithVisibility,
headerAlignmentControl,
} from '../sharedControls';

const config: ControlPanelConfig = {
Expand Down Expand Up @@ -235,6 +236,7 @@ const config: ControlPanelConfig = {
},
},
],
[headerAlignmentControl],
],
},
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,7 @@ describe('BigNumberWithTrendline transformProps', () => {
compareSuffix: 'WoW',
colorPicker: { r: 0, g: 0, b: 0 },
currencyFormat: { symbol: '$', symbolPosition: 'prefix' },
headerAlignment: 'right',
};

const baseDatasource = {
Expand Down Expand Up @@ -141,6 +142,7 @@ describe('BigNumberWithTrendline transformProps', () => {
);
expect(result.bigNumber).toBeNull();
expect(result.subtitle).toBe('subtitle message');
expect(result.headerAlignment).toBe('right');
});

test('should calculate subheader as percent change with suffix', () => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ export default function transformProps(
showXAxisMinMaxLabels = false,
showYAxis = false,
showYAxisMinMaxLabels = false,
headerAlignment,
} = formData;
const granularity = extractTimegrain(rawFormData);
const {
Expand Down Expand Up @@ -416,5 +417,6 @@ export default function transformProps(
onContextMenu,
xValueFormatter: formatTime,
refs,
headerAlignment,
};
}
Loading
Loading