blob: e6626bd53c8dc7edeb731ad09dd31bbfeef6d431 [file] [log] [blame]
/**
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*/
import { AxisType, ChartProps, supersetTheme } from '@superset-ui/core';
import {
LegendOrientation,
LegendType,
} from '@superset-ui/plugin-chart-echarts';
import transformProps from '../../src/Gantt/transformProps';
import {
EchartsGanttChartProps,
EchartsGanttFormData,
} from '../../src/Gantt/types';
const formData: EchartsGanttFormData = {
viz_type: 'gantt_chart',
datasource: '1__table',
startTime: 'startTime',
endTime: 'endTime',
yAxis: {
label: 'Y Axis',
sqlExpression: 'y_axis',
expressionType: 'SQL',
},
tooltipMetrics: ['tooltip_metric'],
tooltipColumns: ['tooltip_column'],
series: 'series',
xAxisTimeFormat: '%H:%M',
tooltipTimeFormat: '%H:%M',
tooltipValuesFormat: 'DURATION_SEC',
colorScheme: 'bnbColors',
zoomable: true,
xAxisTitleMargin: undefined,
yAxisTitleMargin: undefined,
xAxisTimeBounds: [null, '19:00:00'],
subcategories: true,
legendMargin: 0,
legendOrientation: LegendOrientation.Top,
legendType: LegendType.Scroll,
showLegend: true,
sortSeriesAscending: true,
legendSort: null,
};
const queriesData = [
{
data: [
{
startTime: Date.UTC(2025, 1, 1, 13, 0, 0),
endTime: Date.UTC(2025, 1, 1, 14, 0, 0),
'Y Axis': 'first',
tooltip_column: 'tooltip value 1',
series: 'series value 1',
},
{
startTime: Date.UTC(2025, 1, 1, 18, 0, 0),
endTime: Date.UTC(2025, 1, 1, 20, 0, 0),
'Y Axis': 'second',
tooltip_column: 'tooltip value 2',
series: 'series value 2',
},
],
colnames: ['startTime', 'endTime', 'Y Axis', 'tooltip_column', 'series'],
},
];
const chartPropsConfig = {
formData,
queriesData,
theme: supersetTheme,
};
describe('Gantt transformProps', () => {
it('should transform chart props', () => {
const chartProps = new ChartProps(chartPropsConfig);
const transformedProps = transformProps(
chartProps as EchartsGanttChartProps,
);
expect(transformedProps.echartOptions.series).toHaveLength(4);
const series = transformedProps.echartOptions.series as any[];
const series0 = series[0];
const series1 = series[1];
// exclude renderItem because it can't be serialized
expect(typeof series0.renderItem).toBe('function');
delete series0.renderItem;
expect(typeof series1.renderItem).toBe('function');
delete series1.renderItem;
delete transformedProps.echartOptions.series;
expect(transformedProps).toEqual(
expect.objectContaining({
echartOptions: expect.objectContaining({
useUTC: true,
xAxis: {
name: '',
nameGap: 0,
nameLocation: 'middle',
max: Date.UTC(2025, 1, 1, 19, 0, 0),
min: undefined,
type: AxisType.Time,
axisLabel: {
hideOverlap: true,
formatter: expect.anything(),
},
},
yAxis: {
name: '',
nameGap: 0,
nameLocation: 'middle',
type: AxisType.Value,
// always 0
min: 0,
// equals unique categories count
max: 2,
axisLabel: {
show: false,
},
splitLine: {
show: false,
},
},
legend: expect.objectContaining({
show: true,
type: 'scroll',
selector: ['all', 'inverse'],
}),
tooltip: {
formatter: expect.anything(),
},
dataZoom: [
expect.objectContaining({
type: 'slider',
filterMode: 'none',
}),
],
}),
}),
);
expect(series0).toEqual({
name: 'series value 1',
type: 'custom',
progressive: 0,
itemStyle: {
color: expect.anything(),
},
data: [
{
value: [
Date.UTC(2025, 1, 1, 13, 0, 0),
Date.UTC(2025, 1, 1, 14, 0, 0),
0,
2,
Date.UTC(2025, 1, 1, 13, 0, 0),
Date.UTC(2025, 1, 1, 14, 0, 0),
'first',
'tooltip value 1',
'series value 1',
],
},
],
dimensions: [
'startTime',
'endTime',
'index',
'seriesCount',
'startTime',
'endTime',
'Y Axis',
'tooltip_column',
'series',
],
encode: {
x: [0, 1],
},
});
expect(series1).toEqual({
name: 'series value 2',
type: 'custom',
progressive: 0,
itemStyle: {
color: expect.anything(),
},
data: [
{
value: [
Date.UTC(2025, 1, 1, 18, 0, 0),
Date.UTC(2025, 1, 1, 20, 0, 0),
1,
2,
Date.UTC(2025, 1, 1, 18, 0, 0),
Date.UTC(2025, 1, 1, 20, 0, 0),
'second',
'tooltip value 2',
'series value 2',
],
},
],
dimensions: [
'startTime',
'endTime',
'index',
'seriesCount',
'startTime',
'endTime',
'Y Axis',
'tooltip_column',
'series',
],
encode: {
x: [0, 1],
},
});
expect(series[2]).toEqual({
// just for markLines
type: 'line',
animation: false,
markLine: {
data: [{ yAxis: 1 }, { yAxis: 0 }],
label: {
show: false,
},
silent: true,
symbol: ['none', 'none'],
lineStyle: {
type: 'dashed',
color: '#dbe0ea',
},
},
});
expect(series[3]).toEqual({
type: 'line',
animation: false,
markLine: {
data: [
{ yAxis: 1.5, name: 'first' },
{ yAxis: 0.5, name: 'second' },
],
label: {
show: true,
position: 'start',
formatter: '{b}',
color: 'rgba(0,0,0,0.88)',
},
lineStyle: expect.objectContaining({
color: '#00000000',
type: 'solid',
}),
silent: true,
symbol: ['none', 'none'],
},
});
});
});
describe('legend sorting', () => {
const createChartProps = (overrides = {}) =>
new ChartProps({
...chartPropsConfig,
formData: {
...formData,
...overrides,
},
});
it('preserves original data order when no sort specified', () => {
const props = createChartProps({ legendSort: null });
const result = transformProps(props as EchartsGanttChartProps);
const legendData = (result.echartOptions.legend as any).data;
expect(legendData).toEqual(['series value 1', 'series value 2']);
});
it('sorts alphabetically ascending when legendSort is "asc"', () => {
const props = createChartProps({ legendSort: 'asc' });
const result = transformProps(props as EchartsGanttChartProps);
const legendData = (result.echartOptions.legend as any).data;
expect(legendData).toEqual(['series value 1', 'series value 2']);
});
it('sorts alphabetically descending when legendSort is "desc"', () => {
const props = createChartProps({ legendSort: 'desc' });
const result = transformProps(props as EchartsGanttChartProps);
const legendData = (result.echartOptions.legend as any).data;
expect(legendData).toEqual(['series value 2', 'series value 1']);
});
});