diff --git a/superset-frontend/plugins/legacy-plugin-chart-world-map/src/WorldMap.ts b/superset-frontend/plugins/legacy-plugin-chart-world-map/src/WorldMap.ts index e6c7bc2679d..9388c379dd1 100644 --- a/superset-frontend/plugins/legacy-plugin-chart-world-map/src/WorldMap.ts +++ b/superset-frontend/plugins/legacy-plugin-chart-world-map/src/WorldMap.ts @@ -150,14 +150,20 @@ function WorldMap(element: HTMLElement, props: WorldMapProps): void { fillColor: colorFn(d.name, sliceId), })); } else { - colorFn = getSequentialSchemeRegistry() - .get(linearColorScheme) - .createLinearScale(d3Extent(filteredData, d => d.m1)); + const rawExtents = d3Extent(filteredData, d => d.m1); + const extents: [number, number] = + rawExtents[0] != null && rawExtents[1] != null + ? [rawExtents[0], rawExtents[1]] + : [0, 1]; + const colorSchemeObj = getSequentialSchemeRegistry().get(linearColorScheme); + colorFn = colorSchemeObj + ? colorSchemeObj.createLinearScale(extents) + : () => theme.colorBorder; processedData = filteredData.map(d => ({ ...d, radius: radiusScale(Math.sqrt(d.m2)), - fillColor: colorFn(d.m1), + fillColor: colorFn(d.m1) ?? theme.colorBorder, })); } diff --git a/superset-frontend/plugins/legacy-plugin-chart-world-map/test/WorldMap.test.ts b/superset-frontend/plugins/legacy-plugin-chart-world-map/test/WorldMap.test.ts index 5a53aab9e82..4476bcefe85 100644 --- a/superset-frontend/plugins/legacy-plugin-chart-world-map/test/WorldMap.test.ts +++ b/superset-frontend/plugins/legacy-plugin-chart-world-map/test/WorldMap.test.ts @@ -489,6 +489,59 @@ test('popupTemplate returns tooltip HTML when country data exists', () => { expect(tooltipHtml).toContain('hoverinfo'); }); +test('assigns fill colors from sequential scheme when colorBy is metric', () => { + WorldMap(container, { + ...baseProps, + colorBy: ColorBy.Metric, + }); + + const data = lastDatamapConfig?.data as Record< + string, + WorldMapDataEntry & { fillColor: string } + >; + expect(data).toHaveProperty('USA'); + expect(data).toHaveProperty('CAN'); + expect(data.USA).toMatchObject({ + country: 'USA', + name: 'United States', + m1: 100, + }); + // fillColor should be a valid color string from the sequential scale + expect(data.USA.fillColor).toMatch(/^(#|rgb)/); + expect(data.CAN.fillColor).toMatch(/^(#|rgb)/); +}); + +test('falls back to theme.colorBorder when metric values are null', () => { + WorldMap(container, { + ...baseProps, + colorBy: ColorBy.Metric, + data: [ + { + country: 'USA', + name: 'United States', + m1: null as unknown as number, + m2: 200, + code: 'US', + latitude: 37.0902, + longitude: -95.7129, + }, + ], + } as any); + + const data = lastDatamapConfig?.data as Record; + expect(data.USA.fillColor).toBe('#e0e0e0'); +}); + +test('does not throw with empty data and metric coloring', () => { + expect(() => { + WorldMap(container, { + ...baseProps, + colorBy: ColorBy.Metric, + data: [], + }); + }).not.toThrow(); +}); + test('popupTemplate handles null/undefined country data gracefully', () => { WorldMap(container, baseProps);