mirror of
https://github.com/apache/superset.git
synced 2026-04-19 08:04:53 +00:00
fix: Heatmap does not render correctly on normalization (#37208)
This commit is contained in:
committed by
GitHub
parent
61bd8f0cf2
commit
4a7cdccdad
@@ -0,0 +1,82 @@
|
||||
/**
|
||||
* 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 { QueryFormData } from '@superset-ui/core';
|
||||
import buildQuery from '../../src/Heatmap/buildQuery';
|
||||
|
||||
describe('Heatmap buildQuery - Rank Operation for Normalized Field', () => {
|
||||
const baseFormData = {
|
||||
datasource: '5__table',
|
||||
granularity_sqla: 'ds',
|
||||
metric: 'count',
|
||||
x_axis: 'category',
|
||||
groupby: ['region'],
|
||||
viz_type: 'heatmap',
|
||||
} as QueryFormData;
|
||||
|
||||
test('should ALWAYS include rank operation when normalized=true', () => {
|
||||
const formData = {
|
||||
...baseFormData,
|
||||
normalized: true,
|
||||
};
|
||||
|
||||
const queryContext = buildQuery(formData);
|
||||
const [query] = queryContext.queries;
|
||||
|
||||
const rankOperation = query.post_processing?.find(
|
||||
op => op?.operation === 'rank',
|
||||
);
|
||||
|
||||
expect(rankOperation).toBeDefined();
|
||||
expect(rankOperation?.operation).toBe('rank');
|
||||
});
|
||||
|
||||
test('should ALWAYS include rank operation when normalized=false', () => {
|
||||
const formData = {
|
||||
...baseFormData,
|
||||
normalized: false,
|
||||
};
|
||||
|
||||
const queryContext = buildQuery(formData);
|
||||
const [query] = queryContext.queries;
|
||||
|
||||
const rankOperation = query.post_processing?.find(
|
||||
op => op?.operation === 'rank',
|
||||
);
|
||||
|
||||
expect(rankOperation).toBeDefined();
|
||||
expect(rankOperation?.operation).toBe('rank');
|
||||
});
|
||||
|
||||
test('should ALWAYS include rank operation when normalized is undefined', () => {
|
||||
const formData = {
|
||||
...baseFormData,
|
||||
// normalized not set
|
||||
};
|
||||
|
||||
const queryContext = buildQuery(formData);
|
||||
const [query] = queryContext.queries;
|
||||
|
||||
const rankOperation = query.post_processing?.find(
|
||||
op => op?.operation === 'rank',
|
||||
);
|
||||
|
||||
expect(rankOperation).toBeDefined();
|
||||
expect(rankOperation?.operation).toBe('rank');
|
||||
});
|
||||
});
|
||||
@@ -291,4 +291,72 @@ describe('Heatmap transformProps', () => {
|
||||
// Y-axis: numbers sorted numerically (1, 2, 10 NOT 1, 10, 2)
|
||||
expect(yAxisData).toEqual([1, 2, 10]);
|
||||
});
|
||||
|
||||
test('should include rank as 4th dimension when normalized is true', () => {
|
||||
const dataWithRank = [
|
||||
{ day_of_week: 'Monday', hour: 9, count: 10, rank: 0.33 },
|
||||
{ day_of_week: 'Monday', hour: 14, count: 15, rank: 0.67 },
|
||||
{ day_of_week: 'Wednesday', hour: 11, count: 8, rank: 0.17 },
|
||||
{ day_of_week: 'Friday', hour: 16, count: 20, rank: 1.0 },
|
||||
];
|
||||
|
||||
const chartProps = createChartProps({ normalized: true }, dataWithRank);
|
||||
|
||||
const result = transformProps(chartProps as HeatmapChartProps);
|
||||
|
||||
const seriesData = (result.echartOptions.series as any)[0].data;
|
||||
|
||||
// Each data point should be [xIndex, yIndex, metricValue, rankValue]
|
||||
expect(Array.isArray(seriesData)).toBe(true);
|
||||
expect(seriesData.length).toBe(4);
|
||||
|
||||
// Check that data points have 4 dimensions when normalized
|
||||
seriesData.forEach((point: any) => {
|
||||
expect(Array.isArray(point)).toBe(true);
|
||||
expect(point.length).toBe(4);
|
||||
// First two should be indices (numbers)
|
||||
expect(typeof point[0]).toBe('number');
|
||||
expect(typeof point[1]).toBe('number');
|
||||
// Third should be the metric value
|
||||
expect(typeof point[2]).toBe('number');
|
||||
// Fourth should be the rank value
|
||||
expect(typeof point[3]).toBe('number');
|
||||
expect(point[3]).toBeGreaterThanOrEqual(0);
|
||||
expect(point[3]).toBeLessThanOrEqual(1);
|
||||
});
|
||||
|
||||
// visualMap should use dimension 3 (4th element) for coloring
|
||||
expect((result.echartOptions.visualMap as any).dimension).toBe(3);
|
||||
});
|
||||
|
||||
test('should use 3 dimensions when normalized is false', () => {
|
||||
const chartProps = createChartProps({ normalized: false });
|
||||
const result = transformProps(chartProps as HeatmapChartProps);
|
||||
|
||||
const seriesData = (result.echartOptions.series as any)[0].data;
|
||||
|
||||
// Each data point should be [xIndex, yIndex, metricValue]
|
||||
seriesData.forEach((point: any) => {
|
||||
expect(point.length).toBe(3);
|
||||
});
|
||||
|
||||
// visualMap should use dimension 2 (3rd element) for coloring
|
||||
expect((result.echartOptions.visualMap as any).dimension).toBe(2);
|
||||
});
|
||||
|
||||
test('should always hide legend regardless of showLegend setting', () => {
|
||||
// Test with showLegend: true
|
||||
const chartPropsWithLegend = createChartProps({ showLegend: true });
|
||||
const resultWithLegend = transformProps(
|
||||
chartPropsWithLegend as HeatmapChartProps,
|
||||
);
|
||||
expect((resultWithLegend.echartOptions.legend as any).show).toBe(false);
|
||||
|
||||
// Test with showLegend: false
|
||||
const chartPropsWithoutLegend = createChartProps({ showLegend: false });
|
||||
const resultWithoutLegend = transformProps(
|
||||
chartPropsWithoutLegend as HeatmapChartProps,
|
||||
);
|
||||
expect((resultWithoutLegend.echartOptions.legend as any).show).toBe(false);
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user