fix: Changing language doesn't affect echarts charts (#31751)

Co-authored-by: Giampaolo Capelli <giampaolo.capelli@docaposte.fr>
(cherry picked from commit 78efb62781)
This commit is contained in:
Giampaolo Capelli
2025-03-19 19:38:53 +01:00
committed by Michael S. Molina
parent f6f1ffae2f
commit 4a7014b5aa
3 changed files with 59 additions and 32 deletions

View File

@@ -26,7 +26,8 @@
"dependencies": { "dependencies": {
"d3-array": "^1.2.0", "d3-array": "^1.2.0",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"dayjs": "^1.11.13" "dayjs": "^1.11.13",
"@types/react-redux": "^7.1.10"
}, },
"peerDependencies": { "peerDependencies": {
"@superset-ui/chart-controls": "*", "@superset-ui/chart-controls": "*",

View File

@@ -27,8 +27,10 @@ import {
Ref, Ref,
} from 'react'; } from 'react';
import { useSelector } from 'react-redux';
import { styled } from '@superset-ui/core'; import { styled } from '@superset-ui/core';
import { use, init, EChartsType } from 'echarts/core'; import { use, init, EChartsType, registerLocale } from 'echarts/core';
import { import {
SankeyChart, SankeyChart,
PieChart, PieChart,
@@ -60,6 +62,15 @@ import {
} from 'echarts/components'; } from 'echarts/components';
import { LabelLayout } from 'echarts/features'; import { LabelLayout } from 'echarts/features';
import { EchartsHandler, EchartsProps, EchartsStylesProps } from '../types'; import { EchartsHandler, EchartsProps, EchartsStylesProps } from '../types';
import { DEFAULT_LOCALE } from '../constants';
// Define this interface here to avoid creating a dependency back to superset-frontend,
// TODO: to move the type to @superset-ui/core
interface ExplorePageState {
common: {
locale: string;
};
}
const Styles = styled.div<EchartsStylesProps>` const Styles = styled.div<EchartsStylesProps>`
height: ${({ height }) => height}; height: ${({ height }) => height};
@@ -123,24 +134,52 @@ function Echart(
getEchartInstance: () => chartRef.current, getEchartInstance: () => chartRef.current,
})); }));
const locale = useSelector(
(state: ExplorePageState) => state?.common?.locale ?? DEFAULT_LOCALE,
).toUpperCase();
const handleSizeChange = useCallback(
({ width, height }: { width: number; height: number }) => {
if (chartRef.current) {
chartRef.current.resize({ width, height });
}
},
[],
);
useEffect(() => { useEffect(() => {
if (!divRef.current) return; const loadLocaleAndInitChart = async () => {
if (!chartRef.current) { if (!divRef.current) return;
chartRef.current = init(divRef.current);
}
Object.entries(eventHandlers || {}).forEach(([name, handler]) => { const lang = await import(`echarts/lib/i18n/lang${locale}`).catch(e => {
chartRef.current?.off(name); console.error(`Locale ${locale} not supported in ECharts`, e);
chartRef.current?.on(name, handler); });
}); if (lang?.default) {
registerLocale(locale, lang.default);
}
Object.entries(zrEventHandlers || {}).forEach(([name, handler]) => { if (!chartRef.current) {
chartRef.current?.getZr().off(name); chartRef.current = init(divRef.current, null, { locale });
chartRef.current?.getZr().on(name, handler); }
});
chartRef.current.setOption(echartOptions, true); Object.entries(eventHandlers || {}).forEach(([name, handler]) => {
}, [echartOptions, eventHandlers, zrEventHandlers]); chartRef.current?.off(name);
chartRef.current?.on(name, handler);
});
Object.entries(zrEventHandlers || {}).forEach(([name, handler]) => {
chartRef.current?.getZr().off(name);
chartRef.current?.getZr().on(name, handler);
});
chartRef.current.setOption(echartOptions, true);
// did mount
handleSizeChange({ width, height });
};
loadLocaleAndInitChart();
}, [echartOptions, eventHandlers, zrEventHandlers, locale]);
// highlighting // highlighting
useEffect(() => { useEffect(() => {
@@ -158,22 +197,7 @@ function Echart(
}); });
} }
previousSelection.current = currentSelection; previousSelection.current = currentSelection;
}, [currentSelection]); }, [currentSelection, chartRef.current]);
const handleSizeChange = useCallback(
({ width, height }: { width: number; height: number }) => {
if (chartRef.current) {
chartRef.current.resize({ width, height });
}
},
[],
);
// did mount
useEffect(() => {
handleSizeChange({ width, height });
return () => chartRef.current?.dispose();
}, []);
useLayoutEffect(() => { useLayoutEffect(() => {
handleSizeChange({ width, height }); handleSizeChange({ width, height });

View File

@@ -121,3 +121,5 @@ export const TOOLTIP_POINTER_MARGIN = 10;
// If no satisfactory position can be found, how far away // If no satisfactory position can be found, how far away
// from the edge of the window should the tooltip be kept // from the edge of the window should the tooltip be kept
export const TOOLTIP_OVERFLOW_MARGIN = 5; export const TOOLTIP_OVERFLOW_MARGIN = 5;
export const DEFAULT_LOCALE = 'en';