echart的canvas如何在不用i18n的情况下做全局国际化?

公司一个比较大的老项目,vue2,需要做国际化,目前的方案是劫持dom然后做一个映射表进行替换(类似于浏览器自带的翻译)。但是,由于存在大量echart图表,绘制出来的是canvas,就无法获取到dom中的文字。想问一下如何在尽量少入侵代码的情况下,完成echart的国际化?(项目中没有使用i18n,图表涉及的文件近百个,也不好再重新修改,入侵性过大)

想着能不能再echart初始化的时候判断环境然后调用配置表呢

阅读 1.6k
avatarAI BotBETA

在ECharts中实现全局国际化而不直接修改每一个图表配置或引入i18n库,可以通过在ECharts初始化时动态设置语言选项来达成。ECharts 支持通过配置项的 lang 属性来指定语言,但这个属性需要在每个图表的初始化时单独设置。然而,为了减少代码入侵,你可以通过封装ECharts的初始化函数来统一处理语言设置。

以下是一个可能的解决方案,它利用了JavaScript的模块或工具函数来封装ECharts的初始化过程,并在其中加入语言判断的逻辑:

  1. 创建一个封装函数:这个函数负责初始化ECharts实例,并根据当前环境(如通过URL参数、localStorage、cookie等)决定使用哪种语言。
  2. 维护一个语言配置表:这个表包含了不同语言下ECharts需要的所有翻译项。
  3. 在封装函数中应用语言配置:根据当前语言设置,将对应的翻译项应用到ECharts的初始化配置中。

示例代码

首先,你需要一个语言配置表(这里仅示例):

// languageConfig.js
const languageConfig = {
    'en': {
        title: 'Chart Title',
        tooltip: {
            trigger: 'item'
            // 其他英文翻译...
        }
        // 其他英文配置...
    },
    'zh': {
        title: '图表标题',
        tooltip: {
            trigger: 'item'
            // 其他中文翻译...
        }
        // 其他中文配置...
    }
    // 可以添加更多语言...
};

// 获取当前语言,这里只是示例,实际项目中可能需要根据URL、localStorage等来判断
function getCurrentLanguage() {
    // 假设这里返回 'zh' 或 'en'
    return 'zh'; // 示例使用中文
}

// 封装ECharts初始化函数
function initECharts(dom, option, lang = getCurrentLanguage()) {
    const chart = echarts.init(dom);
    // 合并基础配置和当前语言配置
    const mergedOption = {
        ...option,
        lang: languageConfig[lang] // 假设echarts直接支持这样的配置,实际可能需要更复杂的合并逻辑
    };
    chart.setOption(mergedOption);
    return chart;
}

注意:上面的 lang 属性在ECharts中并不直接支持这样的对象配置方式。实际上,ECharts的 lang 属性通常是用来指定一个包含翻译字符串的对象的键,而不是直接传入翻译后的对象。因此,你可能需要调整你的配置表,使其与ECharts的国际化API兼容,或者通过其他方式(如遍历选项并替换文本)来实现国际化。

由于ECharts的国际化API可能并不直接支持复杂的配置对象合并,你可能需要更细致地控制哪些部分需要翻译,并在初始化时手动替换这些部分。

此外,如果你的项目中确实存在大量已经写好的ECharts图表配置,并且这些配置直接硬编码了文本,那么你可能需要编写一个脚本来自动替换这些文本,或者逐步重构这些图表配置以支持国际化。

这个解决方案的关键在于封装和重用,通过封装ECharts的初始化过程,你可以在不修改大量现有代码的情况下,为整个项目添加国际化支持。

2 个回答

image.png

// 保存原始的 fillText 方法
const fillTextOld = CanvasRenderingContext2D.prototype.fillText;

// 定义新的 fillText 方法
const fillTextNew = function(text, x, y, maxWidth) {
  // 修改文字内容
  const modifiedText = text.replace('Mon', '周一').replace('Tue', '星期二');

  // 调用原始的 fillText 方法
  return fillTextOld.call(this, modifiedText, x, y, maxWidth);
};

// 覆盖原型上的 fillText 方法
CanvasRenderingContext2D.prototype.fillText = fillTextNew;
  1. 截图发微信
  2. 打开图片顶部有翻译中文
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
宣传栏