diff --git a/superset-frontend/plugins/plugin-chart-echarts/src/Heatmap/buildQuery.ts b/superset-frontend/plugins/plugin-chart-echarts/src/Heatmap/buildQuery.ts index 858a8ddb3e6..5462f98ba62 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/src/Heatmap/buildQuery.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/src/Heatmap/buildQuery.ts @@ -19,6 +19,7 @@ import { QueryFormColumn, QueryFormData, + QueryObject, QueryFormOrderBy, buildQueryContext, ensureIsArray, @@ -37,17 +38,13 @@ export default function buildQuery(formData: QueryFormData) { ...ensureIsArray(groupby), ]; const orderby: QueryFormOrderBy[] = []; - if (sort_x_axis) { - orderby.push([ - sort_x_axis.includes('value') ? metric : columns[0], - sort_x_axis.includes('asc'), - ]); + if (sort_x_axis && !sort_x_axis.includes('value')) { + // Value sorts are applied post-query; SQL orderby biases row_limit truncation. + orderby.push([columns[0], sort_x_axis.includes('asc')]); } - if (sort_y_axis) { - orderby.push([ - sort_y_axis.includes('value') ? metric : columns[1], - sort_y_axis.includes('asc'), - ]); + if (sort_y_axis && !sort_y_axis.includes('value')) { + // Value sorts are applied post-query; SQL orderby biases row_limit truncation. + orderby.push([columns[1], sort_y_axis.includes('asc')]); } const group_by = normalize_across === 'x' @@ -55,7 +52,7 @@ export default function buildQuery(formData: QueryFormData) { : normalize_across === 'y' ? getColumnLabel(groupby as unknown as QueryFormColumn) : undefined; - return buildQueryContext(formData, baseQueryObject => [ + return buildQueryContext(formData, (baseQueryObject: QueryObject) => [ { ...baseQueryObject, columns, diff --git a/superset-frontend/plugins/plugin-chart-echarts/test/Heatmap/buildQuery.test.ts b/superset-frontend/plugins/plugin-chart-echarts/test/Heatmap/buildQuery.test.ts index 75786f761e5..1aecf0c8cf3 100644 --- a/superset-frontend/plugins/plugin-chart-echarts/test/Heatmap/buildQuery.test.ts +++ b/superset-frontend/plugins/plugin-chart-echarts/test/Heatmap/buildQuery.test.ts @@ -32,7 +32,25 @@ const getQuery = (formData: QueryFormData) => buildQuery(formData).queries[0]; const getRankOperation = (formData: QueryFormData) => getQuery(formData).post_processing?.find(isPostProcessingRank); -test('adds X axis orderby when sorting alphabetically ascending', () => { +test('Heatmap buildQuery omits orderby for value-based ascending X-axis sort', () => { + const query = getQuery({ + ...baseFormData, + sort_x_axis: 'value_asc', + }); + + expect(query.orderby).toEqual([]); +}); + +test('Heatmap buildQuery omits orderby for value-based descending X-axis sort', () => { + const query = getQuery({ + ...baseFormData, + sort_x_axis: 'value_desc', + }); + + expect(query.orderby).toEqual([]); +}); + +test('Heatmap buildQuery adds column orderby for alpha ascending X-axis sort', () => { const query = getQuery({ ...baseFormData, sort_x_axis: 'alpha_asc', @@ -41,7 +59,49 @@ test('adds X axis orderby when sorting alphabetically ascending', () => { expect(query.orderby).toEqual([['category', true]]); }); -test('adds Y axis orderby when sorting alphabetically descending', () => { +test('Heatmap buildQuery adds column orderby for alpha descending X-axis sort', () => { + const query = getQuery({ + ...baseFormData, + sort_x_axis: 'alpha_desc', + }); + + expect(query.orderby).toEqual([['category', false]]); +}); + +test('Heatmap buildQuery omits X-axis orderby when sort_x_axis is not set', () => { + const query = getQuery({ ...baseFormData }); + + expect(query.orderby).toEqual([]); +}); + +test('Heatmap buildQuery omits orderby for value-based ascending Y-axis sort', () => { + const query = getQuery({ + ...baseFormData, + sort_y_axis: 'value_asc', + }); + + expect(query.orderby).toEqual([]); +}); + +test('Heatmap buildQuery omits orderby for value-based descending Y-axis sort', () => { + const query = getQuery({ + ...baseFormData, + sort_y_axis: 'value_desc', + }); + + expect(query.orderby).toEqual([]); +}); + +test('Heatmap buildQuery adds column orderby for alpha ascending Y-axis sort', () => { + const query = getQuery({ + ...baseFormData, + sort_y_axis: 'alpha_asc', + }); + + expect(query.orderby).toEqual([['region', true]]); +}); + +test('Heatmap buildQuery adds column orderby for alpha descending Y-axis sort', () => { const query = getQuery({ ...baseFormData, sort_y_axis: 'alpha_desc', @@ -50,7 +110,13 @@ test('adds Y axis orderby when sorting alphabetically descending', () => { expect(query.orderby).toEqual([['region', false]]); }); -test('should ALWAYS include rank operation when normalized=true', () => { +test('Heatmap buildQuery omits Y-axis orderby when sort_y_axis is not set', () => { + const query = getQuery({ ...baseFormData }); + + expect(query.orderby).toEqual([]); +}); + +test('Heatmap buildQuery always includes rank operation when normalized is true', () => { const rankOperation = getRankOperation({ ...baseFormData, normalized: true, @@ -60,7 +126,7 @@ test('should ALWAYS include rank operation when normalized=true', () => { expect(rankOperation?.operation).toBe('rank'); }); -test('should ALWAYS include rank operation when normalized=false', () => { +test('Heatmap buildQuery always includes rank operation when normalized is false', () => { const rankOperation = getRankOperation({ ...baseFormData, normalized: false, @@ -70,11 +136,8 @@ test('should ALWAYS include rank operation when normalized=false', () => { expect(rankOperation?.operation).toBe('rank'); }); -test('should ALWAYS include rank operation when normalized is undefined', () => { - const rankOperation = getRankOperation({ - ...baseFormData, - // normalized not set - }); +test('Heatmap buildQuery always includes rank operation when normalized is unset', () => { + const rankOperation = getRankOperation({ ...baseFormData }); expect(rankOperation).toBeDefined(); expect(rankOperation?.operation).toBe('rank');