@gooddata/react-components
Version:
GoodData.UI - A powerful JavaScript library for building analytical applications
813 lines (775 loc) • 25.8 kB
text/typescript
// (C) 2019 GoodData Corporation
import {
convertNumberToPercent,
getMinMaxInfo,
getZeroAlignConfiguration,
} from "../getZeroAlignConfiguration";
import { NORMAL_STACK, PERCENT_STACK } from "../getOptionalStackingConfiguration";
import { VisualizationTypes } from "../../../../../constants/visualizationTypes";
import { ISeriesItem, IChartOptions } from "../../../../../interfaces/Config";
describe("getZeroAlignConfiguration", () => {
const numberToYValue = (y: number | null) => ({ y });
const SERIES: ISeriesItem[] = [
{
yAxis: 0,
data: [null, -250, -175, -30, 10, 50, 90, 150].map(numberToYValue),
},
{
yAxis: 1,
data: [100, 500, 900, 1500, 2400, 1100, 350, null].map(numberToYValue),
},
];
it("should return empty config without axis", () => {
const result = getZeroAlignConfiguration({}, {});
expect(result).toEqual({});
});
it("should return empty config with single axis", () => {
const config = {
yAxis: [{}],
};
const result = getZeroAlignConfiguration({}, config);
expect(result).toEqual({});
});
it("should ignore calculation and return yAxis with empty min/max and 'isUserMinMax' is true", () => {
const leftAxisConfig = {
min: 0,
max: 100,
};
const rightAxisConfig = {
min: 0,
max: 1000,
};
const config = {
yAxis: [leftAxisConfig, rightAxisConfig],
series: SERIES,
};
const result = getZeroAlignConfiguration({}, config);
expect(result).toEqual({
yAxis: [
{
isUserMinMax: true,
},
{
isUserMinMax: true,
},
],
});
});
it("should return yAxis with calculated min/max and 'isUserMinMax' is false on both Y axes", () => {
const config = {
yAxis: [{}, {}],
series: SERIES,
};
const result = getZeroAlignConfiguration({}, config);
expect(result).toEqual({
yAxis: [
{
min: -250,
max: 150,
isUserMinMax: false,
},
{
min: -4000,
max: 2400,
isUserMinMax: false,
},
],
});
});
it("should return yAxis with calculated min/max and 'isUserMinMax' is false on single Y axis", () => {
const config = {
yAxis: [
{
min: -100,
max: 100,
},
{},
],
series: SERIES,
};
const result = getZeroAlignConfiguration({}, config);
expect(result).toEqual({
yAxis: [
{
min: -100,
max: 100,
isUserMinMax: true,
},
{
min: -2400,
max: 2400,
isUserMinMax: false,
},
],
});
});
describe("line chart", () => {
const POSITIVE_CHART_SERIES: ISeriesItem[] = [
{
yAxis: 0,
data: [250, 175, 30, 10, 50, 90, 150].map(numberToYValue),
},
{
yAxis: 1,
data: [100, 500, 900, 1500, 2400, 1100, 350].map(numberToYValue),
},
];
const NEGATIVE_CHART_SERIES: ISeriesItem[] = [
{
yAxis: 0,
data: [-250, -175, -30, -10, -50, -90, -150].map(numberToYValue),
},
{
yAxis: 1,
data: [-100, -500, -900, -1500, -2400, -1100, -350].map(numberToYValue),
},
];
const CHART_OPTIONS: IChartOptions = {
type: VisualizationTypes.LINE,
};
it("should return min equal to data min for positive data", () => {
const config = {
yAxis: [{}, {}],
series: POSITIVE_CHART_SERIES,
};
const result = getZeroAlignConfiguration(CHART_OPTIONS, config);
expect(result).toEqual({
yAxis: [
{
min: 10,
max: 250,
isUserMinMax: false,
},
{
min: 100,
max: 2400,
isUserMinMax: false,
},
],
});
});
it("should return min equal to data min for negative data", () => {
const config = {
yAxis: [{}, {}],
series: NEGATIVE_CHART_SERIES,
};
const result = getZeroAlignConfiguration(CHART_OPTIONS, config);
expect(result).toEqual({
yAxis: [
{
min: -250,
max: -10,
isUserMinMax: false,
},
{
min: -2400,
max: -100,
isUserMinMax: false,
},
],
});
});
it("should return min/max equal to data min/max", () => {
const config = {
yAxis: [{}, {}],
series: [...POSITIVE_CHART_SERIES, ...NEGATIVE_CHART_SERIES],
};
const result = getZeroAlignConfiguration(CHART_OPTIONS, config);
expect(result).toEqual({
yAxis: [
{
min: -250,
max: 250,
isUserMinMax: false,
},
{
min: -2400,
max: 2400,
isUserMinMax: false,
},
],
});
});
});
describe("getMinMaxInfo", () => {
const SERIES: ISeriesItem[] = [
{
yAxis: 0,
data: [400, 200, 800, -100, 1000, -200, 600].map(numberToYValue),
},
{
yAxis: 0,
data: [300, 900, 700, 800, -500, 300, -350].map(numberToYValue),
},
{
yAxis: 0,
data: [100, 200, 300, 400, 500, 600, 700].map(numberToYValue),
},
{
yAxis: 1,
data: [-250, -175, -30, 10, 50, 90, 150].map(numberToYValue),
},
{
yAxis: 1,
data: [-500, -400, -300, -200, -100, 0, 100].map(numberToYValue),
},
{
yAxis: 1,
data: [100, 500, 900, 1500, 2400, 1100, 350].map(numberToYValue),
},
];
describe("non-stacked chart", () => {
it.each([
[null, VisualizationTypes.LINE],
[null, VisualizationTypes.COLUMN],
[NORMAL_STACK, VisualizationTypes.LINE],
])(
"should return min/max when stacking is % s and chart type is %s",
(stacking: string, type: string) => {
const config = {
yAxis: [{}, {}],
series: SERIES,
};
const result = getMinMaxInfo(config, stacking, type);
expect(result).toEqual([
{
id: 0,
min: -500,
max: 1000,
isSetMin: false,
isSetMax: false,
},
{
id: 1,
min: -500,
max: 2400,
isSetMin: false,
isSetMax: false,
},
]);
},
);
});
describe("stacked chart", () => {
it("should return min/max in total with normal stack chart", () => {
const config = {
yAxis: [{}, {}],
series: SERIES,
};
const result = getMinMaxInfo(config, NORMAL_STACK, VisualizationTypes.COLUMN);
expect(result).toEqual([
{
id: 0,
min: -500,
max: 1800,
isSetMin: false,
isSetMax: false,
},
{
id: 1,
min: -750,
max: 2450,
isSetMin: false,
isSetMax: false,
},
]);
});
it("should return min/max in percent with percent stack chart", () => {
const config = {
yAxis: [{ opposite: false }, { opposite: true }],
series: SERIES,
};
const result = getMinMaxInfo(config, PERCENT_STACK, VisualizationTypes.COLUMN);
expect(result).toEqual([
{
id: 0,
min: -25,
max: 100,
isSetMin: false,
isSetMax: false,
},
{
id: 1,
min: -750,
max: 2450,
isSetMin: false,
isSetMax: false,
},
]);
});
it("should return user-input min/max with normal stack chart", () => {
const config = {
yAxis: [{ min: -100, max: 300 }, { min: 200 }],
series: SERIES,
};
const result = getMinMaxInfo(config, NORMAL_STACK, VisualizationTypes.COLUMN);
expect(result).toEqual([
{
id: 0,
min: -100,
max: 300,
isSetMin: true,
isSetMax: true,
},
{
id: 1,
min: 200,
max: 2450,
isSetMin: true,
isSetMax: false,
},
]);
});
it("should return user-input min/max with percent stack chart", () => {
const config = {
yAxis: [{ min: 10, max: 80 }, { min: 200 }],
series: SERIES,
};
const result = getMinMaxInfo(config, NORMAL_STACK, VisualizationTypes.COLUMN);
expect(result).toEqual([
{
id: 0,
min: 10,
max: 80,
isSetMin: true,
isSetMax: true,
},
{
id: 1,
min: 200,
max: 2450,
isSetMin: true,
isSetMax: false,
},
]);
});
});
describe("with some null data points", () => {
const SERIES: ISeriesItem[] = [
{
yAxis: 0,
data: [null, null].map(numberToYValue),
},
{
yAxis: 0,
data: [null, null].map(numberToYValue),
},
{
yAxis: 1,
data: [250, null].map(numberToYValue),
},
{
yAxis: 1,
data: [250, 50].map(numberToYValue),
},
];
it.each([
["non-stack chart", null, 0, 250],
["normal stack chart in total", NORMAL_STACK, 0, 500],
["percent stack chart in total", PERCENT_STACK, 0, 100],
])(
"should return min/max with %s",
(_description: string, stacking: string | null, min: number, max: number) => {
const config = {
yAxis: [{}, {}],
series: SERIES,
};
const result = getMinMaxInfo(config, stacking, VisualizationTypes.COLUMN);
expect(result).toEqual([
{
id: 0,
min: 0,
max: 0,
isSetMin: false,
isSetMax: false,
},
{
id: 1,
min,
max,
isSetMin: false,
isSetMax: false,
},
]);
},
);
it("should return user-input min/max with non-stack chart", () => {
const config = {
yAxis: [{ min: 10, max: 100 }, { min: 100 }],
series: SERIES,
};
const result = getMinMaxInfo(config, null, VisualizationTypes.COLUMN);
expect(result).toEqual([
{
id: 0,
min: 10,
max: 100,
isSetMin: true,
isSetMax: true,
},
{
id: 1,
min: 100,
max: 250,
isSetMin: true,
isSetMax: false,
},
]);
});
it("should return user-input min/max with normal stack chart", () => {
const config = {
yAxis: [{ min: 10, max: 100 }, { min: 100 }],
series: SERIES,
};
const result = getMinMaxInfo(config, NORMAL_STACK, VisualizationTypes.COLUMN);
expect(result).toEqual([
{
id: 0,
min: 10,
max: 100,
isSetMin: true,
isSetMax: true,
},
{
id: 1,
min: 100,
max: 500,
isSetMin: true,
isSetMax: false,
},
]);
});
it("should return user-input min/max with percent stack chart", () => {
const config = {
yAxis: [{ min: 10, max: 80 }, { min: 20 }],
series: SERIES,
};
const result = getMinMaxInfo(config, PERCENT_STACK, VisualizationTypes.COLUMN);
expect(result).toEqual([
{
id: 0,
min: 10,
max: 80,
isSetMin: true,
isSetMax: true,
},
{
id: 1,
min: 20,
max: 100,
isSetMin: true,
isSetMax: false,
},
]);
});
});
});
describe("invalid min/max", () => {
const SERIES = [
{
yAxis: 0,
data: [10, 100],
},
{
yAxis: 0,
data: [20, 200],
},
{
yAxis: 1,
data: [10, 100],
},
{
yAxis: 1,
data: [20, 200],
},
];
it.each([[VisualizationTypes.COLUMN], [VisualizationTypes.LINE]])(
"should hide left Y axis when min > max in %s chart",
(chartType: string) => {
const chartOptions = {
type: chartType,
};
const config = {
yAxis: [
{
min: 100,
max: 10,
},
{},
],
series: SERIES,
};
const result = getZeroAlignConfiguration(chartOptions, config);
expect(result).toEqual({
yAxis: [
{
visible: false,
},
{},
],
series: [
{
yAxis: 0,
visible: false,
},
{
yAxis: 0,
visible: false,
},
{
yAxis: 1,
},
{
yAxis: 1,
},
],
});
},
);
it("should hide left and right Y axes when min>max and min=max in column chart", () => {
const chartOptions = {
type: VisualizationTypes.COLUMN,
};
const config = {
yAxis: [
{
min: 100,
max: 10,
},
{
min: 100,
max: 100,
},
],
series: SERIES,
};
const result = getZeroAlignConfiguration(chartOptions, config);
expect(result).toEqual({
yAxis: [
{
visible: false,
},
{
visible: false,
},
],
series: [
{
yAxis: 0,
visible: false,
},
{
yAxis: 0,
visible: false,
},
{
yAxis: 1,
visible: false,
},
{
yAxis: 1,
visible: false,
},
],
});
});
it("should hide left axis when min>max and not hide right axis when min=max in line chart", () => {
const chartOptions = {
type: VisualizationTypes.LINE,
};
const config = {
yAxis: [
{
min: 100,
max: 10,
},
{
min: 100,
max: 100,
},
],
series: SERIES,
};
const result = getZeroAlignConfiguration(chartOptions, config);
expect(result).toEqual({
yAxis: [
{
visible: false,
},
{},
],
series: [
{
yAxis: 0,
visible: false,
},
{
yAxis: 0,
visible: false,
},
{
yAxis: 1,
},
{
yAxis: 1,
},
],
});
});
it("should hide left column axis when min>max and not hide right line axis when min=max in combo chart", () => {
const chartOptions = {
type: VisualizationTypes.COMBO,
};
const series = [
{
type: VisualizationTypes.COLUMN,
yAxis: 0,
data: [10, 100],
},
{
type: VisualizationTypes.COLUMN,
yAxis: 0,
data: [20, 200],
},
{
type: VisualizationTypes.LINE,
yAxis: 1,
data: [10, 100],
},
{
type: VisualizationTypes.LINE,
yAxis: 1,
data: [20, 200],
},
];
const config = {
yAxis: [
{
min: 100,
max: 10,
},
{
min: 100,
max: 100,
},
],
series,
};
const result = getZeroAlignConfiguration(chartOptions, config);
expect(result).toEqual({
yAxis: [
{
visible: false,
},
{},
],
series: [
{
type: VisualizationTypes.COLUMN,
yAxis: 0,
visible: false,
},
{
type: VisualizationTypes.COLUMN,
yAxis: 0,
visible: false,
},
{
type: VisualizationTypes.LINE,
yAxis: 1,
},
{
type: VisualizationTypes.LINE,
yAxis: 1,
},
],
});
});
it("should hide Y axes when min>max in combo chart", () => {
const chartOptions = {
type: VisualizationTypes.COMBO,
};
const series = [
{
type: VisualizationTypes.COLUMN,
yAxis: 0,
data: [10, 100],
},
{
type: VisualizationTypes.COLUMN,
yAxis: 0,
data: [20, 200],
},
{
type: VisualizationTypes.LINE,
yAxis: 1,
data: [10, 100],
},
{
type: VisualizationTypes.LINE,
yAxis: 1,
data: [20, 200],
},
];
const config = {
yAxis: [
{
min: 100,
max: 10,
},
{
min: 200,
max: 100,
},
],
series,
};
const result = getZeroAlignConfiguration(chartOptions, config);
expect(result).toEqual({
yAxis: [
{
visible: false,
},
{
visible: false,
},
],
series: [
{
type: VisualizationTypes.COLUMN,
yAxis: 0,
visible: false,
},
{
type: VisualizationTypes.COLUMN,
yAxis: 0,
visible: false,
},
{
type: VisualizationTypes.LINE,
yAxis: 1,
visible: false,
},
{
type: VisualizationTypes.LINE,
yAxis: 1,
visible: false,
},
],
});
});
});
describe("convertNumberToPercent", () => {
it("should convert number to percent", () => {
const data: number[][] = [
[1, 2, 7],
[10, 40, null],
[10, 90, null],
[null, null, null],
[null, 20, null],
];
const result = convertNumberToPercent(data);
expect(result).toEqual([[10, 20, 70], [20, 80], [10, 90], [], [100]]);
});
});
});