mirror of
https://github.com/apache/superset.git
synced 2026-04-20 00:24:38 +00:00
feat: add sort legend to legend section (#34911)
This commit is contained in:
@@ -27,62 +27,65 @@ import { EchartsBubbleChartProps } from 'plugins/plugin-chart-echarts/src/Bubble
|
||||
|
||||
import transformProps, { formatTooltip } from '../../src/Bubble/transformProps';
|
||||
|
||||
describe('Bubble transformProps', () => {
|
||||
const defaultFormData: SqlaFormData = {
|
||||
datasource: '1__table',
|
||||
viz_type: 'echarts_bubble',
|
||||
entity: 'customer_name',
|
||||
x: 'count',
|
||||
y: {
|
||||
aggregate: 'sum',
|
||||
column: {
|
||||
column_name: 'price_each',
|
||||
},
|
||||
expressionType: 'simple',
|
||||
label: 'SUM(price_each)',
|
||||
const defaultFormData: SqlaFormData = {
|
||||
datasource: '1__table',
|
||||
viz_type: 'echarts_bubble',
|
||||
entity: 'customer_name',
|
||||
x: 'count',
|
||||
y: {
|
||||
aggregate: 'sum',
|
||||
column: {
|
||||
column_name: 'price_each',
|
||||
},
|
||||
size: {
|
||||
aggregate: 'sum',
|
||||
column: {
|
||||
column_name: 'sales',
|
||||
},
|
||||
expressionType: 'simple',
|
||||
label: 'SUM(sales)',
|
||||
expressionType: 'simple',
|
||||
label: 'SUM(price_each)',
|
||||
},
|
||||
size: {
|
||||
aggregate: 'sum',
|
||||
column: {
|
||||
column_name: 'sales',
|
||||
},
|
||||
xAxisBounds: [null, null],
|
||||
yAxisBounds: [null, null],
|
||||
};
|
||||
const chartConfig: ChartPropsConfig = {
|
||||
formData: defaultFormData,
|
||||
height: 800,
|
||||
width: 800,
|
||||
queriesData: [
|
||||
expressionType: 'simple',
|
||||
label: 'SUM(sales)',
|
||||
},
|
||||
xAxisBounds: [null, null],
|
||||
yAxisBounds: [null, null],
|
||||
};
|
||||
|
||||
const queriesData = [
|
||||
{
|
||||
data: [
|
||||
{
|
||||
data: [
|
||||
{
|
||||
customer_name: 'AV Stores, Co.',
|
||||
count: 10,
|
||||
'SUM(price_each)': 20,
|
||||
'SUM(sales)': 30,
|
||||
},
|
||||
{
|
||||
customer_name: 'Alpha Cognac',
|
||||
count: 40,
|
||||
'SUM(price_each)': 50,
|
||||
'SUM(sales)': 60,
|
||||
},
|
||||
{
|
||||
customer_name: 'Amica Models & Co.',
|
||||
count: 70,
|
||||
'SUM(price_each)': 80,
|
||||
'SUM(sales)': 90,
|
||||
},
|
||||
],
|
||||
customer_name: 'AV Stores, Co.',
|
||||
count: 10,
|
||||
'SUM(price_each)': 20,
|
||||
'SUM(sales)': 30,
|
||||
},
|
||||
{
|
||||
customer_name: 'Alpha Cognac',
|
||||
count: 40,
|
||||
'SUM(price_each)': 50,
|
||||
'SUM(sales)': 60,
|
||||
},
|
||||
{
|
||||
customer_name: 'Amica Models & Co.',
|
||||
count: 70,
|
||||
'SUM(price_each)': 80,
|
||||
'SUM(sales)': 90,
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
};
|
||||
},
|
||||
];
|
||||
|
||||
const chartConfig: ChartPropsConfig = {
|
||||
formData: defaultFormData,
|
||||
height: 800,
|
||||
width: 800,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
describe('Bubble transformProps', () => {
|
||||
it('Should transform props for viz', () => {
|
||||
const chartProps = new ChartProps(chartConfig);
|
||||
expect(transformProps(chartProps as EchartsBubbleChartProps)).toEqual(
|
||||
@@ -201,3 +204,49 @@ describe('Bubble formatTooltip', () => {
|
||||
expect(html).toContain('300.0%');
|
||||
});
|
||||
});
|
||||
|
||||
describe('legend sorting', () => {
|
||||
const createChartProps = (overrides = {}) =>
|
||||
new ChartProps({
|
||||
...chartConfig,
|
||||
formData: {
|
||||
...defaultFormData,
|
||||
...overrides,
|
||||
},
|
||||
});
|
||||
it('preserves original data order when no sort specified', () => {
|
||||
const props = createChartProps({ legendSort: null });
|
||||
const result = transformProps(props as EchartsBubbleChartProps);
|
||||
|
||||
const legendData = (result.echartOptions.legend as any).data;
|
||||
expect(legendData).toEqual([
|
||||
'AV Stores, Co.',
|
||||
'Alpha Cognac',
|
||||
'Amica Models & Co.',
|
||||
]);
|
||||
});
|
||||
|
||||
it('sorts alphabetically ascending when legendSort is "asc"', () => {
|
||||
const props = createChartProps({ legendSort: 'asc' });
|
||||
const result = transformProps(props as EchartsBubbleChartProps);
|
||||
|
||||
const legendData = (result.echartOptions.legend as any).data;
|
||||
expect(legendData).toEqual([
|
||||
'Alpha Cognac',
|
||||
'Amica Models & Co.',
|
||||
'AV Stores, Co.',
|
||||
]);
|
||||
});
|
||||
|
||||
it('sorts alphabetically descending when legendSort is "desc"', () => {
|
||||
const props = createChartProps({ legendSort: 'desc' });
|
||||
const result = transformProps(props as EchartsBubbleChartProps);
|
||||
|
||||
const legendData = (result.echartOptions.legend as any).data;
|
||||
expect(legendData).toEqual([
|
||||
'AV Stores, Co.',
|
||||
'Amica Models & Co.',
|
||||
'Alpha Cognac',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,29 +27,30 @@ import {
|
||||
PercentCalcType,
|
||||
} from '../../src/Funnel/types';
|
||||
|
||||
describe('Funnel transformProps', () => {
|
||||
const formData = {
|
||||
colorScheme: 'bnbColors',
|
||||
datasource: '3__table',
|
||||
granularity_sqla: 'ds',
|
||||
metric: 'sum__num',
|
||||
groupby: ['foo', 'bar'],
|
||||
};
|
||||
const chartProps = new ChartProps({
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData: [
|
||||
{
|
||||
data: [
|
||||
{ foo: 'Sylvester', bar: 1, sum__num: 10 },
|
||||
{ foo: 'Arnold', bar: 2, sum__num: 2.5 },
|
||||
],
|
||||
},
|
||||
const formData = {
|
||||
colorScheme: 'bnbColors',
|
||||
datasource: '3__table',
|
||||
granularity_sqla: 'ds',
|
||||
metric: 'sum__num',
|
||||
groupby: ['foo', 'bar'],
|
||||
};
|
||||
const queriesData = [
|
||||
{
|
||||
data: [
|
||||
{ foo: 'Sylvester', bar: 1, sum__num: 10 },
|
||||
{ foo: 'Arnold', bar: 2, sum__num: 2.5 },
|
||||
],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
},
|
||||
];
|
||||
const chartProps = new ChartProps({
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
describe('Funnel transformProps', () => {
|
||||
it('should transform chart props for viz', () => {
|
||||
expect(transformProps(chartProps as EchartsFunnelChartProps)).toEqual(
|
||||
expect.objectContaining({
|
||||
@@ -123,3 +124,49 @@ describe('formatFunnelLabel', () => {
|
||||
).toEqual(['<NULL>', '1.23k', '12.34%']);
|
||||
});
|
||||
});
|
||||
|
||||
describe('legend sorting', () => {
|
||||
const legendQueriesData = [
|
||||
{
|
||||
data: [
|
||||
{ foo: 'Sylvester', sum__num: 10 },
|
||||
{ foo: 'Arnold', sum__num: 2.5 },
|
||||
{ foo: 'Mark', sum__num: 13 },
|
||||
],
|
||||
},
|
||||
];
|
||||
const createChartProps = (overrides = {}) =>
|
||||
new ChartProps({
|
||||
...chartProps,
|
||||
formData: {
|
||||
...formData,
|
||||
groupby: ['foo'],
|
||||
...overrides,
|
||||
},
|
||||
queriesData: legendQueriesData,
|
||||
});
|
||||
|
||||
it('preserves original data order when no sort specified', () => {
|
||||
const props = createChartProps({ legendSort: null });
|
||||
const result = transformProps(props as EchartsFunnelChartProps);
|
||||
|
||||
const legendData = (result.echartOptions.legend as any).data;
|
||||
expect(legendData).toEqual(['Sylvester', 'Arnold', 'Mark']);
|
||||
});
|
||||
|
||||
it('sorts alphabetically ascending when legendSort is "asc"', () => {
|
||||
const props = createChartProps({ legendSort: 'asc' });
|
||||
const result = transformProps(props as EchartsFunnelChartProps);
|
||||
|
||||
const legendData = (result.echartOptions.legend as any).data;
|
||||
expect(legendData).toEqual(['Arnold', 'Mark', 'Sylvester']);
|
||||
});
|
||||
|
||||
it('sorts alphabetically descending when legendSort is "desc"', () => {
|
||||
const props = createChartProps({ legendSort: 'desc' });
|
||||
const result = transformProps(props as EchartsFunnelChartProps);
|
||||
|
||||
const legendData = (result.echartOptions.legend as any).data;
|
||||
expect(legendData).toEqual(['Sylvester', 'Mark', 'Arnold']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -27,63 +27,64 @@ import {
|
||||
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', () => {
|
||||
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,
|
||||
};
|
||||
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,
|
||||
};
|
||||
|
||||
it('should transform chart props', () => {
|
||||
const chartProps = new ChartProps(chartPropsConfig);
|
||||
const transformedProps = transformProps(
|
||||
@@ -267,3 +268,38 @@ describe('Gantt transformProps', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
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']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,43 +21,43 @@ import transformProps from '../../src/Graph/transformProps';
|
||||
import { DEFAULT_GRAPH_SERIES_OPTION } from '../../src/Graph/constants';
|
||||
import { EchartsGraphChartProps } from '../../src/Graph/types';
|
||||
|
||||
const formData: SqlaFormData = {
|
||||
colorScheme: 'bnbColors',
|
||||
datasource: '3__table',
|
||||
granularity_sqla: 'ds',
|
||||
metric: 'count',
|
||||
source: 'source_column',
|
||||
target: 'target_column',
|
||||
category: null,
|
||||
viz_type: 'graph',
|
||||
};
|
||||
const queriesData = [
|
||||
{
|
||||
colnames: ['source_column', 'target_column', 'count'],
|
||||
data: [
|
||||
{
|
||||
source_column: 'source_value_1',
|
||||
target_column: 'target_value_1',
|
||||
count: 6,
|
||||
},
|
||||
{
|
||||
source_column: 'source_value_2',
|
||||
target_column: 'target_value_2',
|
||||
count: 5,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const chartPropsConfig = {
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
describe('EchartsGraph transformProps', () => {
|
||||
it('should transform chart props for viz without category', () => {
|
||||
const formData: SqlaFormData = {
|
||||
colorScheme: 'bnbColors',
|
||||
datasource: '3__table',
|
||||
granularity_sqla: 'ds',
|
||||
metric: 'count',
|
||||
source: 'source_column',
|
||||
target: 'target_column',
|
||||
category: null,
|
||||
viz_type: 'graph',
|
||||
};
|
||||
const queriesData = [
|
||||
{
|
||||
colnames: ['source_column', 'target_column', 'count'],
|
||||
data: [
|
||||
{
|
||||
source_column: 'source_value_1',
|
||||
target_column: 'target_value_1',
|
||||
count: 6,
|
||||
},
|
||||
{
|
||||
source_column: 'source_value_2',
|
||||
target_column: 'target_value_2',
|
||||
count: 5,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const chartPropsConfig = {
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
const chartProps = new ChartProps(chartPropsConfig);
|
||||
expect(transformProps(chartProps as EchartsGraphChartProps)).toEqual(
|
||||
expect.objectContaining({
|
||||
@@ -263,3 +263,91 @@ describe('EchartsGraph transformProps', () => {
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
describe('legend sorting', () => {
|
||||
const queriesData = [
|
||||
{
|
||||
colnames: [
|
||||
'source_column',
|
||||
'target_column',
|
||||
'source_category_column',
|
||||
'target_category_column',
|
||||
'count',
|
||||
],
|
||||
data: [
|
||||
{
|
||||
source_column: 'source_value',
|
||||
target_column: 'target_value',
|
||||
source_category_column: 'category_value_1',
|
||||
target_category_column: 'category_value_3',
|
||||
count: 6,
|
||||
},
|
||||
{
|
||||
source_column: 'source_value',
|
||||
target_column: 'target_value',
|
||||
source_category_column: 'category_value_3',
|
||||
target_category_column: 'category_value_2',
|
||||
count: 5,
|
||||
},
|
||||
{
|
||||
source_column: 'source_value',
|
||||
target_column: 'target_value',
|
||||
source_category_column: 'category_value_2',
|
||||
target_category_column: 'category_value_1',
|
||||
count: 4,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const getChartProps = (overrides = {}) =>
|
||||
new ChartProps({
|
||||
...chartPropsConfig,
|
||||
formData: {
|
||||
...formData,
|
||||
...overrides,
|
||||
sourceCategory: 'source_category_column',
|
||||
targetCategory: 'target_category_column',
|
||||
},
|
||||
queriesData,
|
||||
});
|
||||
|
||||
it('sort legend by data', () => {
|
||||
const chartProps = getChartProps({
|
||||
legendSort: null,
|
||||
});
|
||||
const transformed = transformProps(chartProps as EchartsGraphChartProps);
|
||||
|
||||
expect((transformed.echartOptions.legend as any).data).toEqual([
|
||||
'category_value_1',
|
||||
'category_value_3',
|
||||
'category_value_2',
|
||||
]);
|
||||
});
|
||||
|
||||
it('sort legend by label ascending', () => {
|
||||
const chartProps = getChartProps({
|
||||
legendSort: 'asc',
|
||||
});
|
||||
const transformed = transformProps(chartProps as EchartsGraphChartProps);
|
||||
|
||||
expect((transformed.echartOptions.legend as any).data).toEqual([
|
||||
'category_value_1',
|
||||
'category_value_2',
|
||||
'category_value_3',
|
||||
]);
|
||||
});
|
||||
|
||||
it('sort legend by label descending', () => {
|
||||
const chartProps = getChartProps({
|
||||
legendSort: 'desc',
|
||||
});
|
||||
const transformed = transformProps(chartProps as EchartsGraphChartProps);
|
||||
|
||||
expect((transformed.echartOptions.legend as any).data).toEqual([
|
||||
'category_value_3',
|
||||
'category_value_2',
|
||||
'category_value_1',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -81,6 +81,7 @@ const formData: EchartsMixedTimeseriesFormData = {
|
||||
forecastPeriods: [],
|
||||
forecastInterval: 0,
|
||||
forecastSeasonalityDaily: 0,
|
||||
legendSort: null,
|
||||
};
|
||||
|
||||
const queriesData = [
|
||||
@@ -197,3 +198,63 @@ it('should transform chart props for viz with showQueryIdentifiers=true', () =>
|
||||
'sum__num (Query B), boy',
|
||||
]);
|
||||
});
|
||||
|
||||
describe('legend sorting', () => {
|
||||
const getChartProps = (overrides = {}) =>
|
||||
new ChartProps({
|
||||
...chartPropsConfig,
|
||||
formData: {
|
||||
...formData,
|
||||
...overrides,
|
||||
showQueryIdentifiers: true,
|
||||
},
|
||||
});
|
||||
|
||||
it('sort legend by data', () => {
|
||||
const chartProps = getChartProps({
|
||||
legendSort: null,
|
||||
});
|
||||
const transformed = transformProps(
|
||||
chartProps as EchartsMixedTimeseriesProps,
|
||||
);
|
||||
|
||||
expect((transformed.echartOptions.legend as any).data).toEqual([
|
||||
'sum__num (Query A), girl',
|
||||
'sum__num (Query A), boy',
|
||||
'sum__num (Query B), girl',
|
||||
'sum__num (Query B), boy',
|
||||
]);
|
||||
});
|
||||
|
||||
it('sort legend by label ascending', () => {
|
||||
const chartProps = getChartProps({
|
||||
legendSort: 'asc',
|
||||
});
|
||||
const transformed = transformProps(
|
||||
chartProps as EchartsMixedTimeseriesProps,
|
||||
);
|
||||
|
||||
expect((transformed.echartOptions.legend as any).data).toEqual([
|
||||
'sum__num (Query A), boy',
|
||||
'sum__num (Query A), girl',
|
||||
'sum__num (Query B), boy',
|
||||
'sum__num (Query B), girl',
|
||||
]);
|
||||
});
|
||||
|
||||
it('sort legend by label descending', () => {
|
||||
const chartProps = getChartProps({
|
||||
legendSort: 'desc',
|
||||
});
|
||||
const transformed = transformProps(
|
||||
chartProps as EchartsMixedTimeseriesProps,
|
||||
);
|
||||
|
||||
expect((transformed.echartOptions.legend as any).data).toEqual([
|
||||
'sum__num (Query B), girl',
|
||||
'sum__num (Query B), boy',
|
||||
'sum__num (Query A), girl',
|
||||
'sum__num (Query A), boy',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -446,7 +446,7 @@ describe('Other category', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('Sort Legend', () => {
|
||||
describe('legend sorting', () => {
|
||||
const defaultFormData: SqlaFormData = {
|
||||
colorScheme: 'bnbColors',
|
||||
datasource: '3__table',
|
||||
|
||||
@@ -42,54 +42,56 @@ interface RadarSeriesData {
|
||||
name: string;
|
||||
}
|
||||
|
||||
describe('Radar transformProps', () => {
|
||||
const formData: Partial<EchartsRadarFormData> = {
|
||||
colorScheme: 'supersetColors',
|
||||
datasource: '3__table',
|
||||
granularity_sqla: 'ds',
|
||||
columnConfig: {
|
||||
'MAX(na_sales)': {
|
||||
radarMetricMaxValue: null,
|
||||
radarMetricMinValue: 0,
|
||||
},
|
||||
'SUM(eu_sales)': {
|
||||
radarMetricMaxValue: 5000,
|
||||
},
|
||||
const formData: Partial<EchartsRadarFormData> = {
|
||||
colorScheme: 'supersetColors',
|
||||
datasource: '3__table',
|
||||
granularity_sqla: 'ds',
|
||||
columnConfig: {
|
||||
'MAX(na_sales)': {
|
||||
radarMetricMaxValue: null,
|
||||
radarMetricMinValue: 0,
|
||||
},
|
||||
groupby: [],
|
||||
metrics: [
|
||||
'MAX(na_sales)',
|
||||
'SUM(jp_sales)',
|
||||
'SUM(other_sales)',
|
||||
'SUM(eu_sales)',
|
||||
],
|
||||
viz_type: 'radar',
|
||||
numberFormat: 'SMART_NUMBER',
|
||||
dateFormat: 'smart_date',
|
||||
showLegend: true,
|
||||
showLabels: true,
|
||||
isCircle: false,
|
||||
};
|
||||
'SUM(eu_sales)': {
|
||||
radarMetricMaxValue: 5000,
|
||||
},
|
||||
},
|
||||
groupby: [],
|
||||
metrics: [
|
||||
'MAX(na_sales)',
|
||||
'SUM(jp_sales)',
|
||||
'SUM(other_sales)',
|
||||
'SUM(eu_sales)',
|
||||
],
|
||||
viz_type: 'radar',
|
||||
numberFormat: 'SMART_NUMBER',
|
||||
dateFormat: 'smart_date',
|
||||
showLegend: true,
|
||||
showLabels: true,
|
||||
isCircle: false,
|
||||
};
|
||||
|
||||
const chartProps = new ChartProps({
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData: [
|
||||
const queriesData = [
|
||||
{
|
||||
data: [
|
||||
{
|
||||
data: [
|
||||
{
|
||||
'MAX(na_sales)': 41.49,
|
||||
'SUM(jp_sales)': 1290.99,
|
||||
'SUM(other_sales)': 797.73,
|
||||
'SUM(eu_sales)': 2434.13,
|
||||
},
|
||||
],
|
||||
'MAX(na_sales)': 41.49,
|
||||
'SUM(jp_sales)': 1290.99,
|
||||
'SUM(other_sales)': 797.73,
|
||||
'SUM(eu_sales)': 2434.13,
|
||||
},
|
||||
],
|
||||
theme: supersetTheme,
|
||||
});
|
||||
},
|
||||
];
|
||||
|
||||
const chartProps = new ChartProps({
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
});
|
||||
|
||||
describe('Radar transformProps', () => {
|
||||
it('should transform chart props for normalized radar chart & normalize all metrics except the ones with custom min & max', () => {
|
||||
const transformedProps = transformProps(
|
||||
chartProps as EchartsRadarChartProps,
|
||||
@@ -125,3 +127,77 @@ describe('Radar transformProps', () => {
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
describe('legend sorting', () => {
|
||||
const legendSortData = [
|
||||
{
|
||||
data: [
|
||||
{
|
||||
name: 'Sylvester sales',
|
||||
'SUM(jp_sales)': 1290.99,
|
||||
'SUM(other_sales)': 797.73,
|
||||
'SUM(eu_sales)': 2434.13,
|
||||
},
|
||||
{
|
||||
name: 'Arnold sales',
|
||||
'SUM(jp_sales)': 290.99,
|
||||
'SUM(other_sales)': 627.73,
|
||||
'SUM(eu_sales)': 434.13,
|
||||
},
|
||||
{
|
||||
name: 'Mark sales',
|
||||
'SUM(jp_sales)': 2290.99,
|
||||
'SUM(other_sales)': 1297.73,
|
||||
'SUM(eu_sales)': 934.13,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
const createChartProps = (overrides = {}) =>
|
||||
new ChartProps({
|
||||
...chartProps,
|
||||
formData: {
|
||||
...formData,
|
||||
groupby: ['name'],
|
||||
metrics: ['SUM(jp_sales)', 'SUM(other_sales)', 'SUM(eu_sales)'],
|
||||
...overrides,
|
||||
},
|
||||
queriesData: legendSortData,
|
||||
});
|
||||
|
||||
it('preserves original data order when no sort specified', () => {
|
||||
const props = createChartProps({ legendSort: null });
|
||||
const result = transformProps(props as EchartsRadarChartProps);
|
||||
|
||||
const legendData = (result.echartOptions.legend as any).data;
|
||||
expect(legendData).toEqual([
|
||||
'Sylvester sales',
|
||||
'Arnold sales',
|
||||
'Mark sales',
|
||||
]);
|
||||
});
|
||||
|
||||
it('sorts alphabetically ascending when legendSort is "asc"', () => {
|
||||
const props = createChartProps({ legendSort: 'asc' });
|
||||
const result = transformProps(props as EchartsRadarChartProps);
|
||||
|
||||
const legendData = (result.echartOptions.legend as any).data;
|
||||
expect(legendData).toEqual([
|
||||
'Arnold sales',
|
||||
'Mark sales',
|
||||
'Sylvester sales',
|
||||
]);
|
||||
});
|
||||
|
||||
it('sorts alphabetically descending when legendSort is "desc"', () => {
|
||||
const props = createChartProps({ legendSort: 'desc' });
|
||||
const result = transformProps(props as EchartsRadarChartProps);
|
||||
|
||||
const legendData = (result.echartOptions.legend as any).data;
|
||||
expect(legendData).toEqual([
|
||||
'Sylvester sales',
|
||||
'Mark sales',
|
||||
'Arnold sales',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -31,31 +31,31 @@ import {
|
||||
import { EchartsTimeseriesChartProps } from '../../src/types';
|
||||
import transformProps from '../../src/Timeseries/transformProps';
|
||||
|
||||
describe('EchartsTimeseries transformProps', () => {
|
||||
const formData: SqlaFormData = {
|
||||
colorScheme: 'bnbColors',
|
||||
datasource: '3__table',
|
||||
granularity_sqla: 'ds',
|
||||
metric: 'sum__num',
|
||||
groupby: ['foo', 'bar'],
|
||||
viz_type: 'my_viz',
|
||||
};
|
||||
const queriesData = [
|
||||
{
|
||||
data: [
|
||||
{ 'San Francisco': 1, 'New York': 2, __timestamp: 599616000000 },
|
||||
{ 'San Francisco': 3, 'New York': 4, __timestamp: 599916000000 },
|
||||
],
|
||||
},
|
||||
];
|
||||
const chartPropsConfig = {
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
const formData: SqlaFormData = {
|
||||
colorScheme: 'bnbColors',
|
||||
datasource: '3__table',
|
||||
granularity_sqla: 'ds',
|
||||
metric: 'sum__num',
|
||||
groupby: ['foo', 'bar'],
|
||||
viz_type: 'my_viz',
|
||||
};
|
||||
const queriesData = [
|
||||
{
|
||||
data: [
|
||||
{ 'San Francisco': 1, 'New York': 2, __timestamp: 599616000000 },
|
||||
{ 'San Francisco': 3, 'New York': 4, __timestamp: 599916000000 },
|
||||
],
|
||||
},
|
||||
];
|
||||
const chartPropsConfig = {
|
||||
formData,
|
||||
width: 800,
|
||||
height: 600,
|
||||
queriesData,
|
||||
theme: supersetTheme,
|
||||
};
|
||||
|
||||
describe('EchartsTimeseries transformProps', () => {
|
||||
it('should transform chart props for viz', () => {
|
||||
const chartProps = new ChartProps(chartPropsConfig);
|
||||
expect(transformProps(chartProps as EchartsTimeseriesChartProps)).toEqual(
|
||||
@@ -625,3 +625,101 @@ describe('Does transformProps transform series correctly', () => {
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
describe('legend sorting', () => {
|
||||
const legendSortData = [
|
||||
{
|
||||
data: [
|
||||
{
|
||||
Milton: 40,
|
||||
'San Francisco': 1,
|
||||
'New York': 2,
|
||||
Boston: 1,
|
||||
__timestamp: 599616000000,
|
||||
},
|
||||
{
|
||||
Milton: 20,
|
||||
'San Francisco': 3,
|
||||
'New York': 4,
|
||||
Boston: 1,
|
||||
__timestamp: 599916000000,
|
||||
},
|
||||
{
|
||||
Milton: 60,
|
||||
'San Francisco': 5,
|
||||
'New York': 8,
|
||||
Boston: 6,
|
||||
__timestamp: 600216000000,
|
||||
},
|
||||
{
|
||||
Milton: 10,
|
||||
'San Francisco': 2,
|
||||
'New York': 7,
|
||||
Boston: 2,
|
||||
__timestamp: 600516000000,
|
||||
},
|
||||
],
|
||||
},
|
||||
];
|
||||
|
||||
const getChartProps = (formData: Partial<SqlaFormData>) =>
|
||||
new ChartProps({
|
||||
...chartPropsConfig,
|
||||
formData: { ...formData },
|
||||
queriesData: legendSortData,
|
||||
});
|
||||
|
||||
it('sort legend by data', () => {
|
||||
const chartProps = getChartProps({
|
||||
legendSort: null,
|
||||
sortSeriesType: 'min',
|
||||
sortSeriesAscending: true,
|
||||
});
|
||||
const transformed = transformProps(
|
||||
chartProps as EchartsTimeseriesChartProps,
|
||||
);
|
||||
|
||||
expect((transformed.echartOptions.legend as any).data).toEqual([
|
||||
'San Francisco',
|
||||
'Boston',
|
||||
'New York',
|
||||
'Milton',
|
||||
]);
|
||||
});
|
||||
|
||||
it('sort legend by label ascending', () => {
|
||||
const chartProps = getChartProps({
|
||||
legendSort: 'asc',
|
||||
sortSeriesType: 'min',
|
||||
sortSeriesAscending: true,
|
||||
});
|
||||
const transformed = transformProps(
|
||||
chartProps as EchartsTimeseriesChartProps,
|
||||
);
|
||||
|
||||
expect((transformed.echartOptions.legend as any).data).toEqual([
|
||||
'Boston',
|
||||
'Milton',
|
||||
'New York',
|
||||
'San Francisco',
|
||||
]);
|
||||
});
|
||||
|
||||
it('sort legend by label descending', () => {
|
||||
const chartProps = getChartProps({
|
||||
legendSort: 'desc',
|
||||
sortSeriesType: 'min',
|
||||
sortSeriesAscending: true,
|
||||
});
|
||||
const transformed = transformProps(
|
||||
chartProps as EchartsTimeseriesChartProps,
|
||||
);
|
||||
|
||||
expect((transformed.echartOptions.legend as any).data).toEqual([
|
||||
'San Francisco',
|
||||
'New York',
|
||||
'Milton',
|
||||
'Boston',
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user