This is an automated email from the ASF dual-hosted git repository.

rusackas pushed a commit to branch d3-localization
in repository https://gitbox.apache.org/repos/asf/superset.git

commit 74416d9882865cde10d648d1779e253a7a54f142
Author: Evan Rusackas <e...@rusackas.com>
AuthorDate: Tue Aug 12 11:43:18 2025 -0700

    fix(echarts): Apply D3 locale formatting to adaptive datetime x-axis
    
    Fixes #31790
    
    When the "Adaptive" datetime format option was selected for x-axis in 
ECharts
    visualizations, the custom D3 locale settings (like localized month names) 
were
    being ignored. This was because getXAxisFormatter() was returning undefined 
for
    SMART_DATE_ID, causing ECharts to use its default formatter instead of the
    configured D3 locale formatter.
    
    The fix ensures that when SMART_DATE_ID is selected, the smart date 
formatter
    with proper locale support is returned, allowing custom D3 time formats with
    localized month and day names to work correctly with the adaptive option.
    
    🤖 Generated with [Claude Code](https://claude.ai/code)
    
    Co-Authored-By: Claude <nore...@anthropic.com>
---
 superset-frontend/package-lock.json                |  2 +-
 .../plugin-chart-echarts/src/utils/formatters.ts   |  5 ++-
 .../test/utils/formatters.test.ts                  | 50 +++++++++++++++++++++-
 3 files changed, 53 insertions(+), 4 deletions(-)

diff --git a/superset-frontend/package-lock.json 
b/superset-frontend/package-lock.json
index ad6ac17411..5442463535 100644
--- a/superset-frontend/package-lock.json
+++ b/superset-frontend/package-lock.json
@@ -61644,7 +61644,7 @@
         "@storybook/types": "8.4.7",
         "@types/react-loadable": "^5.5.11",
         "core-js": "3.40.0",
-        "gh-pages": "^6.2.0",
+        "gh-pages": "^6.3.0",
         "jquery": "^3.7.1",
         "memoize-one": "^5.2.1",
         "react": "^17.0.2",
diff --git 
a/superset-frontend/plugins/plugin-chart-echarts/src/utils/formatters.ts 
b/superset-frontend/plugins/plugin-chart-echarts/src/utils/formatters.ts
index 65961e0889..5077da626b 100644
--- a/superset-frontend/plugins/plugin-chart-echarts/src/utils/formatters.ts
+++ b/superset-frontend/plugins/plugin-chart-echarts/src/utils/formatters.ts
@@ -89,7 +89,10 @@ export function getTooltipTimeFormatter(
 export function getXAxisFormatter(
   format?: string,
 ): TimeFormatter | StringConstructor | undefined {
-  if (format === SMART_DATE_ID || !format) {
+  if (format === SMART_DATE_ID) {
+    return getSmartDateFormatter();
+  }
+  if (!format) {
     return undefined;
   }
   if (format) {
diff --git 
a/superset-frontend/plugins/plugin-chart-echarts/test/utils/formatters.test.ts 
b/superset-frontend/plugins/plugin-chart-echarts/test/utils/formatters.test.ts
index f8d40a5bd1..fb47deafa0 100644
--- 
a/superset-frontend/plugins/plugin-chart-echarts/test/utils/formatters.test.ts
+++ 
b/superset-frontend/plugins/plugin-chart-echarts/test/utils/formatters.test.ts
@@ -16,8 +16,16 @@
  * specific language governing permissions and limitations
  * under the License.
  */
-import { NumberFormats } from '@superset-ui/core';
-import { getPercentFormatter } from '../../src/utils/formatters';
+import {
+  NumberFormats,
+  SMART_DATE_ID,
+  getTimeFormatter,
+} from '@superset-ui/core';
+import {
+  getPercentFormatter,
+  getXAxisFormatter,
+  getSmartDateFormatter,
+} from '../../src/utils/formatters';
 
 describe('getPercentFormatter', () => {
   const value = 0.6;
@@ -35,3 +43,41 @@ describe('getPercentFormatter', () => {
     ).toEqual('60.00%');
   });
 });
+
+describe('getXAxisFormatter', () => {
+  it('should return smart date formatter when SMART_DATE_ID is specified', () 
=> {
+    const formatter = getXAxisFormatter(SMART_DATE_ID);
+    expect(formatter).toBeDefined();
+    expect(formatter).toBeInstanceOf(Function);
+    // The formatter should be the same as getSmartDateFormatter()
+    const smartDateFormatter = getSmartDateFormatter();
+    expect(formatter).toEqual(smartDateFormatter);
+  });
+
+  it('should return undefined when format is not specified', () => {
+    const formatter = getXAxisFormatter();
+    expect(formatter).toBeUndefined();
+  });
+
+  it('should return undefined when format is empty string', () => {
+    const formatter = getXAxisFormatter('');
+    expect(formatter).toBeUndefined();
+  });
+
+  it('should return the appropriate time formatter for a specific format', () 
=> {
+    const format = '%Y-%m-%d';
+    const formatter = getXAxisFormatter(format);
+    expect(formatter).toBeDefined();
+    expect(formatter).toBeInstanceOf(Function);
+    // Should return the same formatter as getTimeFormatter
+    const expectedFormatter = getTimeFormatter(format);
+    expect(formatter).toEqual(expectedFormatter);
+  });
+
+  it('should return String constructor as fallback', () => {
+    // This test verifies that the String constructor is returned
+    // Note: the current logic may not reach this case, but keeping for 
completeness
+    const formatter = getXAxisFormatter(null as any);
+    expect(formatter).toBeUndefined();
+  });
+});

Reply via email to