mirror of
https://github.com/apache/superset.git
synced 2026-05-12 19:35:17 +00:00
fix(plugin-chart-echarts): support truncated numeric x-axis (#26215)
Co-authored-by: Michael S. Molina <michael.s.molina@gmail.com>
(cherry picked from commit 07e5fe8a66)
This commit is contained in:
committed by
Michael S. Molina
parent
b699df7030
commit
d0961d0ed8
@@ -26,6 +26,7 @@ export const DEFAULT_FORM_DATA: Partial<EchartsBubbleFormData> = {
|
|||||||
logYAxis: false,
|
logYAxis: false,
|
||||||
xAxisTitleMargin: 30,
|
xAxisTitleMargin: 30,
|
||||||
yAxisTitleMargin: 30,
|
yAxisTitleMargin: 30,
|
||||||
|
truncateXAxis: false,
|
||||||
truncateYAxis: false,
|
truncateYAxis: false,
|
||||||
yAxisBounds: [null, null],
|
yAxisBounds: [null, null],
|
||||||
xAxisLabelRotation: 0,
|
xAxisLabelRotation: 0,
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ import {
|
|||||||
} from '@superset-ui/chart-controls';
|
} from '@superset-ui/chart-controls';
|
||||||
|
|
||||||
import { DEFAULT_FORM_DATA } from './constants';
|
import { DEFAULT_FORM_DATA } from './constants';
|
||||||
import { legendSection } from '../controls';
|
import { legendSection, truncateXAxis, xAxisBounds } from '../controls';
|
||||||
|
|
||||||
const { logAxis, truncateYAxis, yAxisBounds, xAxisLabelRotation, opacity } =
|
const { logAxis, truncateYAxis, yAxisBounds, xAxisLabelRotation, opacity } =
|
||||||
DEFAULT_FORM_DATA;
|
DEFAULT_FORM_DATA;
|
||||||
@@ -247,6 +247,8 @@ const config: ControlPanelConfig = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
[truncateXAxis],
|
||||||
|
[xAxisBounds],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: 'truncateYAxis',
|
name: 'truncateYAxis',
|
||||||
|
|||||||
@@ -28,9 +28,9 @@ import {
|
|||||||
import { EchartsBubbleChartProps, EchartsBubbleFormData } from './types';
|
import { EchartsBubbleChartProps, EchartsBubbleFormData } from './types';
|
||||||
import { DEFAULT_FORM_DATA, MINIMUM_BUBBLE_SIZE } from './constants';
|
import { DEFAULT_FORM_DATA, MINIMUM_BUBBLE_SIZE } from './constants';
|
||||||
import { defaultGrid } from '../defaults';
|
import { defaultGrid } from '../defaults';
|
||||||
import { getLegendProps } from '../utils/series';
|
import { getLegendProps, getMinAndMaxFromBounds } from '../utils/series';
|
||||||
import { Refs } from '../types';
|
import { Refs } from '../types';
|
||||||
import { parseYAxisBound } from '../utils/controls';
|
import { parseAxisBound } from '../utils/controls';
|
||||||
import { getDefaultTooltip } from '../utils/tooltip';
|
import { getDefaultTooltip } from '../utils/tooltip';
|
||||||
import { getPadding } from '../Timeseries/transformers';
|
import { getPadding } from '../Timeseries/transformers';
|
||||||
import { convertInteger } from '../utils/convertInteger';
|
import { convertInteger } from '../utils/convertInteger';
|
||||||
@@ -84,6 +84,7 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
|||||||
series: bubbleSeries,
|
series: bubbleSeries,
|
||||||
xAxisLabel: bubbleXAxisTitle,
|
xAxisLabel: bubbleXAxisTitle,
|
||||||
yAxisLabel: bubbleYAxisTitle,
|
yAxisLabel: bubbleYAxisTitle,
|
||||||
|
xAxisBounds,
|
||||||
xAxisFormat,
|
xAxisFormat,
|
||||||
yAxisFormat,
|
yAxisFormat,
|
||||||
yAxisBounds,
|
yAxisBounds,
|
||||||
@@ -91,6 +92,7 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
|||||||
logYAxis,
|
logYAxis,
|
||||||
xAxisTitleMargin,
|
xAxisTitleMargin,
|
||||||
yAxisTitleMargin,
|
yAxisTitleMargin,
|
||||||
|
truncateXAxis,
|
||||||
truncateYAxis,
|
truncateYAxis,
|
||||||
xAxisLabelRotation,
|
xAxisLabelRotation,
|
||||||
yAxisLabelRotation,
|
yAxisLabelRotation,
|
||||||
@@ -141,7 +143,8 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
|||||||
const yAxisFormatter = getNumberFormatter(yAxisFormat);
|
const yAxisFormatter = getNumberFormatter(yAxisFormat);
|
||||||
const tooltipSizeFormatter = getNumberFormatter(tooltipSizeFormat);
|
const tooltipSizeFormatter = getNumberFormatter(tooltipSizeFormat);
|
||||||
|
|
||||||
const [min, max] = yAxisBounds.map(parseYAxisBound);
|
const [xAxisMin, xAxisMax] = xAxisBounds.map(parseAxisBound);
|
||||||
|
const [yAxisMin, yAxisMax] = yAxisBounds.map(parseAxisBound);
|
||||||
|
|
||||||
const padding = getPadding(
|
const padding = getPadding(
|
||||||
showLegend,
|
showLegend,
|
||||||
@@ -155,6 +158,7 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
|||||||
convertInteger(xAxisTitleMargin),
|
convertInteger(xAxisTitleMargin),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const xAxisType = logXAxis ? AxisType.log : AxisType.value;
|
||||||
const echartOptions: EChartsCoreOption = {
|
const echartOptions: EChartsCoreOption = {
|
||||||
series,
|
series,
|
||||||
xAxis: {
|
xAxis: {
|
||||||
@@ -172,7 +176,8 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
|||||||
fontWight: 'bolder',
|
fontWight: 'bolder',
|
||||||
},
|
},
|
||||||
nameGap: convertInteger(xAxisTitleMargin),
|
nameGap: convertInteger(xAxisTitleMargin),
|
||||||
type: logXAxis ? AxisType.log : AxisType.value,
|
type: xAxisType,
|
||||||
|
...getMinAndMaxFromBounds(xAxisType, truncateXAxis, xAxisMin, xAxisMax),
|
||||||
},
|
},
|
||||||
yAxis: {
|
yAxis: {
|
||||||
axisLabel: { formatter: yAxisFormatter },
|
axisLabel: { formatter: yAxisFormatter },
|
||||||
@@ -189,8 +194,8 @@ export default function transformProps(chartProps: EchartsBubbleChartProps) {
|
|||||||
fontWight: 'bolder',
|
fontWight: 'bolder',
|
||||||
},
|
},
|
||||||
nameGap: convertInteger(yAxisTitleMargin),
|
nameGap: convertInteger(yAxisTitleMargin),
|
||||||
min,
|
min: yAxisMin,
|
||||||
max,
|
max: yAxisMax,
|
||||||
type: logYAxis ? AxisType.log : AxisType.value,
|
type: logYAxis ? AxisType.log : AxisType.value,
|
||||||
},
|
},
|
||||||
legend: {
|
legend: {
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ import {
|
|||||||
ForecastSeriesEnum,
|
ForecastSeriesEnum,
|
||||||
Refs,
|
Refs,
|
||||||
} from '../types';
|
} from '../types';
|
||||||
import { parseYAxisBound } from '../utils/controls';
|
import { parseAxisBound } from '../utils/controls';
|
||||||
import {
|
import {
|
||||||
getOverMaxHiddenFormatter,
|
getOverMaxHiddenFormatter,
|
||||||
dedupSeries,
|
dedupSeries,
|
||||||
@@ -345,9 +345,9 @@ export default function transformProps(
|
|||||||
});
|
});
|
||||||
|
|
||||||
// yAxisBounds need to be parsed to replace incompatible values with undefined
|
// yAxisBounds need to be parsed to replace incompatible values with undefined
|
||||||
let [min, max] = (yAxisBounds || []).map(parseYAxisBound);
|
let [min, max] = (yAxisBounds || []).map(parseAxisBound);
|
||||||
let [minSecondary, maxSecondary] = (yAxisBoundsSecondary || []).map(
|
let [minSecondary, maxSecondary] = (yAxisBoundsSecondary || []).map(
|
||||||
parseYAxisBound,
|
parseAxisBound,
|
||||||
);
|
);
|
||||||
|
|
||||||
const array = ensureIsArray(chartProps.rawFormData?.time_compare);
|
const array = ensureIsArray(chartProps.rawFormData?.time_compare);
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ import {
|
|||||||
richTooltipSection,
|
richTooltipSection,
|
||||||
seriesOrderSection,
|
seriesOrderSection,
|
||||||
percentageThresholdControl,
|
percentageThresholdControl,
|
||||||
|
truncateXAxis,
|
||||||
|
xAxisBounds,
|
||||||
} from '../../controls';
|
} from '../../controls';
|
||||||
import { AreaChartStackControlOptions } from '../../constants';
|
import { AreaChartStackControlOptions } from '../../constants';
|
||||||
|
|
||||||
@@ -241,6 +243,8 @@ const config: ControlPanelConfig = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
[truncateXAxis],
|
||||||
|
[xAxisBounds],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: 'truncateYAxis',
|
name: 'truncateYAxis',
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ import {
|
|||||||
richTooltipSection,
|
richTooltipSection,
|
||||||
seriesOrderSection,
|
seriesOrderSection,
|
||||||
showValueSection,
|
showValueSection,
|
||||||
|
truncateXAxis,
|
||||||
|
xAxisBounds,
|
||||||
} from '../../../controls';
|
} from '../../../controls';
|
||||||
|
|
||||||
import { OrientationType } from '../../types';
|
import { OrientationType } from '../../types';
|
||||||
@@ -224,6 +226,8 @@ function createAxisControl(axis: 'x' | 'y'): ControlSetRow[] {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
[truncateXAxis],
|
||||||
|
[xAxisBounds],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: 'truncateYAxis',
|
name: 'truncateYAxis',
|
||||||
|
|||||||
@@ -38,6 +38,8 @@ import {
|
|||||||
richTooltipSection,
|
richTooltipSection,
|
||||||
seriesOrderSection,
|
seriesOrderSection,
|
||||||
showValueSection,
|
showValueSection,
|
||||||
|
truncateXAxis,
|
||||||
|
xAxisBounds,
|
||||||
} from '../../../controls';
|
} from '../../../controls';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -229,6 +231,8 @@ const config: ControlPanelConfig = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
[truncateXAxis],
|
||||||
|
[xAxisBounds],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: 'truncateYAxis',
|
name: 'truncateYAxis',
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ import {
|
|||||||
richTooltipSection,
|
richTooltipSection,
|
||||||
seriesOrderSection,
|
seriesOrderSection,
|
||||||
showValueSection,
|
showValueSection,
|
||||||
|
truncateXAxis,
|
||||||
|
xAxisBounds,
|
||||||
} from '../../../controls';
|
} from '../../../controls';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -173,6 +175,8 @@ const config: ControlPanelConfig = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
[truncateXAxis],
|
||||||
|
[xAxisBounds],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: 'truncateYAxis',
|
name: 'truncateYAxis',
|
||||||
|
|||||||
@@ -37,6 +37,8 @@ import {
|
|||||||
richTooltipSection,
|
richTooltipSection,
|
||||||
seriesOrderSection,
|
seriesOrderSection,
|
||||||
showValueSectionWithoutStack,
|
showValueSectionWithoutStack,
|
||||||
|
truncateXAxis,
|
||||||
|
xAxisBounds,
|
||||||
} from '../../../controls';
|
} from '../../../controls';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -173,6 +175,8 @@ const config: ControlPanelConfig = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
[truncateXAxis],
|
||||||
|
[xAxisBounds],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: 'truncateYAxis',
|
name: 'truncateYAxis',
|
||||||
|
|||||||
@@ -35,6 +35,8 @@ import {
|
|||||||
richTooltipSection,
|
richTooltipSection,
|
||||||
seriesOrderSection,
|
seriesOrderSection,
|
||||||
showValueSection,
|
showValueSection,
|
||||||
|
truncateXAxis,
|
||||||
|
xAxisBounds,
|
||||||
} from '../../controls';
|
} from '../../controls';
|
||||||
|
|
||||||
const {
|
const {
|
||||||
@@ -223,6 +225,8 @@ const config: ControlPanelConfig = {
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
[truncateXAxis],
|
||||||
|
[xAxisBounds],
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: 'truncateYAxis',
|
name: 'truncateYAxis',
|
||||||
|
|||||||
@@ -57,6 +57,7 @@ export const DEFAULT_FORM_DATA: EchartsTimeseriesFormData = {
|
|||||||
seriesType: EchartsTimeseriesSeriesType.Line,
|
seriesType: EchartsTimeseriesSeriesType.Line,
|
||||||
stack: false,
|
stack: false,
|
||||||
tooltipTimeFormat: 'smart_date',
|
tooltipTimeFormat: 'smart_date',
|
||||||
|
truncateXAxis: true,
|
||||||
truncateYAxis: false,
|
truncateYAxis: false,
|
||||||
yAxisBounds: [null, null],
|
yAxisBounds: [null, null],
|
||||||
zoomable: false,
|
zoomable: false,
|
||||||
|
|||||||
@@ -54,7 +54,7 @@ import {
|
|||||||
} from './types';
|
} from './types';
|
||||||
import { DEFAULT_FORM_DATA } from './constants';
|
import { DEFAULT_FORM_DATA } from './constants';
|
||||||
import { ForecastSeriesEnum, ForecastValue, Refs } from '../types';
|
import { ForecastSeriesEnum, ForecastValue, Refs } from '../types';
|
||||||
import { parseYAxisBound } from '../utils/controls';
|
import { parseAxisBound } from '../utils/controls';
|
||||||
import {
|
import {
|
||||||
calculateLowerLogTick,
|
calculateLowerLogTick,
|
||||||
dedupSeries,
|
dedupSeries,
|
||||||
@@ -64,6 +64,7 @@ import {
|
|||||||
getAxisType,
|
getAxisType,
|
||||||
getColtypesMapping,
|
getColtypesMapping,
|
||||||
getLegendProps,
|
getLegendProps,
|
||||||
|
getMinAndMaxFromBounds,
|
||||||
} from '../utils/series';
|
} from '../utils/series';
|
||||||
import {
|
import {
|
||||||
extractAnnotationLabels,
|
extractAnnotationLabels,
|
||||||
@@ -161,8 +162,10 @@ export default function transformProps(
|
|||||||
stack,
|
stack,
|
||||||
tooltipTimeFormat,
|
tooltipTimeFormat,
|
||||||
tooltipSortByMetric,
|
tooltipSortByMetric,
|
||||||
|
truncateXAxis,
|
||||||
truncateYAxis,
|
truncateYAxis,
|
||||||
xAxis: xAxisOrig,
|
xAxis: xAxisOrig,
|
||||||
|
xAxisBounds,
|
||||||
xAxisLabelRotation,
|
xAxisLabelRotation,
|
||||||
xAxisSortSeries,
|
xAxisSortSeries,
|
||||||
xAxisSortSeriesAscending,
|
xAxisSortSeriesAscending,
|
||||||
@@ -388,15 +391,20 @@ export default function transformProps(
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// yAxisBounds need to be parsed to replace incompatible values with undefined
|
// axis bounds need to be parsed to replace incompatible values with undefined
|
||||||
let [min, max] = (yAxisBounds || []).map(parseYAxisBound);
|
const [xAxisMin, xAxisMax] = (xAxisBounds || []).map(parseAxisBound);
|
||||||
|
let [yAxisMin, yAxisMax] = (yAxisBounds || []).map(parseAxisBound);
|
||||||
|
|
||||||
// default to 0-100% range when doing row-level contribution chart
|
// default to 0-100% range when doing row-level contribution chart
|
||||||
if ((contributionMode === 'row' || isAreaExpand) && stack) {
|
if ((contributionMode === 'row' || isAreaExpand) && stack) {
|
||||||
if (min === undefined) min = 0;
|
if (yAxisMin === undefined) yAxisMin = 0;
|
||||||
if (max === undefined) max = 1;
|
if (yAxisMax === undefined) yAxisMax = 1;
|
||||||
} else if (logAxis && min === undefined && minPositiveValue !== undefined) {
|
} else if (
|
||||||
min = calculateLowerLogTick(minPositiveValue);
|
logAxis &&
|
||||||
|
yAxisMin === undefined &&
|
||||||
|
minPositiveValue !== undefined
|
||||||
|
) {
|
||||||
|
yAxisMin = calculateLowerLogTick(minPositiveValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
const tooltipFormatter =
|
const tooltipFormatter =
|
||||||
@@ -452,12 +460,14 @@ export default function transformProps(
|
|||||||
xAxisType === AxisType.time && timeGrainSqla
|
xAxisType === AxisType.time && timeGrainSqla
|
||||||
? TIMEGRAIN_TO_TIMESTAMP[timeGrainSqla]
|
? TIMEGRAIN_TO_TIMESTAMP[timeGrainSqla]
|
||||||
: 0,
|
: 0,
|
||||||
|
...getMinAndMaxFromBounds(xAxisType, truncateXAxis, xAxisMin, xAxisMax),
|
||||||
};
|
};
|
||||||
|
|
||||||
let yAxis: any = {
|
let yAxis: any = {
|
||||||
...defaultYAxis,
|
...defaultYAxis,
|
||||||
type: logAxis ? AxisType.log : AxisType.value,
|
type: logAxis ? AxisType.log : AxisType.value,
|
||||||
min,
|
min: yAxisMin,
|
||||||
max,
|
max: yAxisMax,
|
||||||
minorTick: { show: true },
|
minorTick: { show: true },
|
||||||
minorSplitLine: { show: minorSplitLine },
|
minorSplitLine: { show: minorSplitLine },
|
||||||
axisLabel: {
|
axisLabel: {
|
||||||
|
|||||||
@@ -75,10 +75,12 @@ export type EchartsTimeseriesFormData = QueryFormData & {
|
|||||||
stack: StackType;
|
stack: StackType;
|
||||||
timeCompare?: string[];
|
timeCompare?: string[];
|
||||||
tooltipTimeFormat?: string;
|
tooltipTimeFormat?: string;
|
||||||
|
truncateXAxis: boolean;
|
||||||
truncateYAxis: boolean;
|
truncateYAxis: boolean;
|
||||||
yAxisFormat?: string;
|
yAxisFormat?: string;
|
||||||
xAxisTimeFormat?: string;
|
xAxisTimeFormat?: string;
|
||||||
timeGrainSqla?: TimeGranularity;
|
timeGrainSqla?: TimeGranularity;
|
||||||
|
xAxisBounds: [number | undefined | null, number | undefined | null];
|
||||||
yAxisBounds: [number | undefined | null, number | undefined | null];
|
yAxisBounds: [number | undefined | null, number | undefined | null];
|
||||||
zoomable: boolean;
|
zoomable: boolean;
|
||||||
richTooltip: boolean;
|
richTooltip: boolean;
|
||||||
|
|||||||
@@ -248,3 +248,34 @@ export const seriesOrderSection: ControlSetRow[] = [
|
|||||||
[sortSeriesType],
|
[sortSeriesType],
|
||||||
[sortSeriesAscending],
|
[sortSeriesAscending],
|
||||||
];
|
];
|
||||||
|
|
||||||
|
export const truncateXAxis: ControlSetItem = {
|
||||||
|
name: 'truncateXAxis',
|
||||||
|
config: {
|
||||||
|
type: 'CheckboxControl',
|
||||||
|
label: t('Truncate X Axis'),
|
||||||
|
default: DEFAULT_FORM_DATA.truncateXAxis,
|
||||||
|
renderTrigger: true,
|
||||||
|
description: t(
|
||||||
|
'Truncate X Axis. Can be overridden by specifying a min or max bound. Only applicable for numercal X axis.',
|
||||||
|
),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
export const xAxisBounds: ControlSetItem = {
|
||||||
|
name: 'xAxisBounds',
|
||||||
|
config: {
|
||||||
|
type: 'BoundsControl',
|
||||||
|
label: t('X Axis Bounds'),
|
||||||
|
renderTrigger: true,
|
||||||
|
default: DEFAULT_FORM_DATA.xAxisBounds,
|
||||||
|
description: t(
|
||||||
|
'Bounds for numerical X axis. Not applicable for temporal or categorical axes. ' +
|
||||||
|
'When left empty, the bounds are dynamically defined based on the min/max of the data. ' +
|
||||||
|
"Note that this feature will only expand the axis range. It won't " +
|
||||||
|
"narrow the data's extent.",
|
||||||
|
),
|
||||||
|
visibility: ({ controls }: ControlPanelsContainerProps) =>
|
||||||
|
Boolean(controls?.truncateXAxis?.value),
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|||||||
@@ -20,7 +20,7 @@
|
|||||||
import { validateNumber } from '@superset-ui/core';
|
import { validateNumber } from '@superset-ui/core';
|
||||||
|
|
||||||
// eslint-disable-next-line import/prefer-default-export
|
// eslint-disable-next-line import/prefer-default-export
|
||||||
export function parseYAxisBound(
|
export function parseAxisBound(
|
||||||
bound?: string | number | null,
|
bound?: string | number | null,
|
||||||
): number | undefined {
|
): number | undefined {
|
||||||
if (bound === undefined || bound === null || Number.isNaN(Number(bound))) {
|
if (bound === undefined || bound === null || Number.isNaN(Number(bound))) {
|
||||||
|
|||||||
@@ -543,3 +543,17 @@ export function calculateLowerLogTick(minPositiveValue: number) {
|
|||||||
const logBase10 = Math.floor(Math.log10(minPositiveValue));
|
const logBase10 = Math.floor(Math.log10(minPositiveValue));
|
||||||
return Math.pow(10, logBase10);
|
return Math.pow(10, logBase10);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getMinAndMaxFromBounds(
|
||||||
|
axisType: AxisType,
|
||||||
|
truncateAxis: boolean,
|
||||||
|
min?: number,
|
||||||
|
max?: number,
|
||||||
|
): { min: number | 'dataMin'; max: number | 'dataMax' } | {} {
|
||||||
|
return truncateAxis && axisType === AxisType.value
|
||||||
|
? {
|
||||||
|
min: min === undefined ? 'dataMin' : min,
|
||||||
|
max: max === undefined ? 'dataMax' : max,
|
||||||
|
}
|
||||||
|
: {};
|
||||||
|
}
|
||||||
|
|||||||
@@ -48,6 +48,7 @@ describe('Bubble transformProps', () => {
|
|||||||
expressionType: 'simple',
|
expressionType: 'simple',
|
||||||
label: 'SUM(sales)',
|
label: 'SUM(sales)',
|
||||||
},
|
},
|
||||||
|
xAxisBounds: [null, null],
|
||||||
yAxisBounds: [null, null],
|
yAxisBounds: [null, null],
|
||||||
};
|
};
|
||||||
const chartProps = new ChartProps({
|
const chartProps = new ChartProps({
|
||||||
|
|||||||
@@ -16,22 +16,22 @@
|
|||||||
* specific language governing permissions and limitations
|
* specific language governing permissions and limitations
|
||||||
* under the License.
|
* under the License.
|
||||||
*/
|
*/
|
||||||
import { parseYAxisBound } from '../../src/utils/controls';
|
import { parseAxisBound } from '../../src/utils/controls';
|
||||||
|
|
||||||
describe('parseYAxisBound', () => {
|
describe('parseYAxisBound', () => {
|
||||||
it('should return undefined for invalid values', () => {
|
it('should return undefined for invalid values', () => {
|
||||||
expect(parseYAxisBound(null)).toBeUndefined();
|
expect(parseAxisBound(null)).toBeUndefined();
|
||||||
expect(parseYAxisBound(undefined)).toBeUndefined();
|
expect(parseAxisBound(undefined)).toBeUndefined();
|
||||||
expect(parseYAxisBound(NaN)).toBeUndefined();
|
expect(parseAxisBound(NaN)).toBeUndefined();
|
||||||
expect(parseYAxisBound('abc')).toBeUndefined();
|
expect(parseAxisBound('abc')).toBeUndefined();
|
||||||
});
|
});
|
||||||
|
|
||||||
it('should return numeric value for valid values', () => {
|
it('should return numeric value for valid values', () => {
|
||||||
expect(parseYAxisBound(0)).toEqual(0);
|
expect(parseAxisBound(0)).toEqual(0);
|
||||||
expect(parseYAxisBound('0')).toEqual(0);
|
expect(parseAxisBound('0')).toEqual(0);
|
||||||
expect(parseYAxisBound(1)).toEqual(1);
|
expect(parseAxisBound(1)).toEqual(1);
|
||||||
expect(parseYAxisBound('1')).toEqual(1);
|
expect(parseAxisBound('1')).toEqual(1);
|
||||||
expect(parseYAxisBound(10.1)).toEqual(10.1);
|
expect(parseAxisBound(10.1)).toEqual(10.1);
|
||||||
expect(parseYAxisBound('10.1')).toEqual(10.1);
|
expect(parseAxisBound('10.1')).toEqual(10.1);
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -36,6 +36,7 @@ import {
|
|||||||
getChartPadding,
|
getChartPadding,
|
||||||
getLegendProps,
|
getLegendProps,
|
||||||
getOverMaxHiddenFormatter,
|
getOverMaxHiddenFormatter,
|
||||||
|
getMinAndMaxFromBounds,
|
||||||
sanitizeHtml,
|
sanitizeHtml,
|
||||||
sortAndFilterSeries,
|
sortAndFilterSeries,
|
||||||
sortRows,
|
sortRows,
|
||||||
@@ -879,3 +880,30 @@ test('getAxisType', () => {
|
|||||||
expect(getAxisType(GenericDataType.BOOLEAN)).toEqual(AxisType.category);
|
expect(getAxisType(GenericDataType.BOOLEAN)).toEqual(AxisType.category);
|
||||||
expect(getAxisType(GenericDataType.STRING)).toEqual(AxisType.category);
|
expect(getAxisType(GenericDataType.STRING)).toEqual(AxisType.category);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('getMinAndMaxFromBounds returns empty object when not truncating', () => {
|
||||||
|
expect(getMinAndMaxFromBounds(AxisType.value, false, 10, 100)).toEqual({});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getMinAndMaxFromBounds returns automatic bounds when truncating', () => {
|
||||||
|
expect(
|
||||||
|
getMinAndMaxFromBounds(AxisType.value, true, undefined, undefined),
|
||||||
|
).toEqual({
|
||||||
|
min: 'dataMin',
|
||||||
|
max: 'dataMax',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getMinAndMaxFromBounds returns automatic upper bound when truncating', () => {
|
||||||
|
expect(getMinAndMaxFromBounds(AxisType.value, true, 10, undefined)).toEqual({
|
||||||
|
min: 10,
|
||||||
|
max: 'dataMax',
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test('getMinAndMaxFromBounds returns automatic lower bound when truncating', () => {
|
||||||
|
expect(getMinAndMaxFromBounds(AxisType.value, true, undefined, 100)).toEqual({
|
||||||
|
min: 'dataMin',
|
||||||
|
max: 100,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|||||||
Reference in New Issue
Block a user