From 3bf7b2e7c7fb3891ee4de2b71b0d000c07cbe4a7 Mon Sep 17 00:00:00 2001 From: plainheart Date: Mon, 25 Oct 2021 00:14:37 +0800 Subject: [PATCH 1/5] fix(calendar): i18n isn't working in calendar coordinate system, resolves #15932. --- src/component/calendar/CalendarView.ts | 84 +++++++++++++++----------- src/coord/calendar/CalendarModel.ts | 19 +++--- test/calendar-week.html | 19 ++++-- 3 files changed, 73 insertions(+), 49 deletions(-) diff --git a/src/component/calendar/CalendarView.ts b/src/component/calendar/CalendarView.ts index d1e15972ec..547f524e8e 100644 --- a/src/component/calendar/CalendarView.ts +++ b/src/component/calendar/CalendarView.ts @@ -20,36 +20,18 @@ import * as zrUtil from 'zrender/src/core/util'; import * as graphic from '../../util/graphic'; import {createTextStyle} from '../../label/labelStyle'; -import * as formatUtil from '../../util/format'; -import * as numberUtil from '../../util/number'; -import CalendarModel from '../../coord/calendar/CalendarModel'; +import { formatTplSimple } from '../../util/format'; +import { parsePercent } from '../../util/number'; +import type CalendarModel from '../../coord/calendar/CalendarModel'; import {CalendarParsedDateRangeInfo, CalendarParsedDateInfo} from '../../coord/calendar/Calendar'; -import GlobalModel from '../../model/Global'; -import ExtensionAPI from '../../core/ExtensionAPI'; +import type GlobalModel from '../../model/Global'; +import type ExtensionAPI from '../../core/ExtensionAPI'; import { LayoutOrient, OptionDataValueDate, ZRTextAlign, ZRTextVerticalAlign } from '../../util/types'; import ComponentView from '../../view/Component'; import { PathStyleProps } from 'zrender/src/graphic/Path'; import { TextStyleProps, TextProps } from 'zrender/src/graphic/Text'; - -const MONTH_TEXT = { - EN: [ - 'Jan', 'Feb', 'Mar', - 'Apr', 'May', 'Jun', - 'Jul', 'Aug', 'Sep', - 'Oct', 'Nov', 'Dec' - ], - CN: [ - '一月', '二月', '三月', - '四月', '五月', '六月', - '七月', '八月', '九月', - '十月', '十一月', '十二月' - ] -}; - -const WEEK_TEXT = { - EN: ['S', 'M', 'T', 'W', 'T', 'F', 'S'], - CN: ['日', '一', '二', '三', '四', '五', '六'] -}; +import { LocaleOption, getLocaleModel } from '../../core/locale'; +import type Model from '../../model/Model'; class CalendarView extends ComponentView { @@ -88,6 +70,9 @@ class CalendarView extends ComponentView { const rangeData = coordSys.getRangeInfo(); const orient = coordSys.getOrient(); + // locale + const localeModel = ecModel.getLocaleModel(); + this._renderDayRect(calendarModel, rangeData, group); // _renderLines must be called prior to following function @@ -95,9 +80,9 @@ class CalendarView extends ComponentView { this._renderYearText(calendarModel, rangeData, orient, group); - this._renderMonthText(calendarModel, orient, group); + this._renderMonthText(calendarModel, localeModel, orient, group); - this._renderWeekText(calendarModel, rangeData, orient, group); + this._renderWeekText(calendarModel, localeModel, rangeData, orient, group); } // render day rect @@ -245,7 +230,7 @@ class CalendarView extends ComponentView { ) { if (typeof formatter === 'string' && formatter) { - return formatUtil.formatTplSimple(formatter, params); + return formatTplSimple(formatter, params); } if (typeof formatter === 'function') { @@ -403,7 +388,12 @@ class CalendarView extends ComponentView { } // render month and year text - _renderMonthText(calendarModel: CalendarModel, orient: LayoutOrient, group: graphic.Group) { + _renderMonthText( + calendarModel: CalendarModel, + localeModel: Model, + orient: LayoutOrient, + group: graphic.Group + ) { const monthLabel = calendarModel.getModel('monthLabel'); if (!monthLabel.get('show')) { @@ -417,8 +407,16 @@ class CalendarView extends ComponentView { const termPoints = [this._tlpoints, this._blpoints]; - if (zrUtil.isString(nameMap)) { - nameMap = MONTH_TEXT[nameMap.toUpperCase() as 'CN' | 'EN'] || []; + if (!nameMap || zrUtil.isString(nameMap)) { + if (nameMap) { + const nameMapUpperCase = (nameMap as string).toUpperCase(); + localeModel = getLocaleModel(nameMapUpperCase === 'CN' ? 'ZH' : nameMapUpperCase) || localeModel; + } + // PENDING + // for ZH locale, original form is `一月` but current form is `1月` + // Consider adding a new configuration for each locale? + // For example, `time.monthShortcut` or `calendar.month` + nameMap = localeModel.get(['time', 'monthAbbr']) || []; } const idx = pos === 'start' ? 0 : 1; @@ -493,6 +491,7 @@ class CalendarView extends ComponentView { // render weeks _renderWeekText( calendarModel: CalendarModel, + localeModel: Model, rangeData: CalendarParsedDateRangeInfo, orient: LayoutOrient, group: graphic.Group @@ -509,8 +508,23 @@ class CalendarView extends ComponentView { let margin = dayLabel.get('margin'); const firstDayOfWeek = coordSys.getFirstDayOfWeek(); - if (zrUtil.isString(nameMap)) { - nameMap = WEEK_TEXT[nameMap.toUpperCase() as 'CN' | 'EN'] || []; + if (!nameMap || zrUtil.isString(nameMap)) { + if (nameMap) { + const nameMapUpperCase = (nameMap as string).toUpperCase(); + localeModel = getLocaleModel(nameMapUpperCase === 'CN' ? 'ZH' : nameMapUpperCase) || localeModel; + } + // PENDING: + // Current each word of `dayOfWeekAbbr` in `EN` locale is a bit long. + // Use the capital as shortcut. + // ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] + // ↓ + // ['S', 'M', 'T', 'W', 'T', 'F', 'S'] + // Or consider adding a new configuration for each locale? + // For example, `time.dayOfWeekShortcut` or `calendar.dayOfWeek` + nameMap = zrUtil.map( + localeModel.get(['time', 'dayOfWeekAbbr']) || [], + val => val[0] + ); } let start = coordSys.getNextNDay( @@ -518,7 +532,7 @@ class CalendarView extends ComponentView { ).time; const cellSize = [coordSys.getCellWidth(), coordSys.getCellHeight()]; - margin = numberUtil.parsePercent(margin, Math.min(cellSize[1], cellSize[0])); + margin = parsePercent(margin, Math.min(cellSize[1], cellSize[0])); if (pos === 'start') { start = coordSys.getNextNDay( @@ -546,4 +560,4 @@ class CalendarView extends ComponentView { } } -export default CalendarView; \ No newline at end of file +export default CalendarView; diff --git a/src/coord/calendar/CalendarModel.ts b/src/coord/calendar/CalendarModel.ts index 1e8e1179de..8930b9c9d6 100644 --- a/src/coord/calendar/CalendarModel.ts +++ b/src/coord/calendar/CalendarModel.ts @@ -105,11 +105,12 @@ export interface CalendarOption extends ComponentOption, BoxLayoutOptionMixin { position?: 'start' | 'end' /** - * Week text content, defaults to 'en'; It supports Chinese, English, and custom; index 0 always means Sunday - * en: shortcut to English ['S', 'M', 'T', 'W', 'T', 'F', 'S'] - * cn: shortcut to Chinese ['日', '一', '二', '三', '四', '五', '六'] + * Week text content + * defaults to auto-detected locale by the browser or the specifed locale by `echarts.init` function; + * It supports the default built-in locale name: EN, ZH/CN; or ant other registed locale name; or customized array + * index 0 always means Sunday */ - nameMap?: 'en' | 'cn' | string[] + nameMap?: 'en' | 'cn' | 'zh' | string[] } monthLabel?: Omit & { @@ -124,9 +125,12 @@ export interface CalendarOption extends ComponentOption, BoxLayoutOptionMixin { position?: 'start' | 'end' /** - * Month text content, defaults to 'en'; It supports Chinese, English, and custom; Index 0 always means Jan; + * Month text content + * defaults to auto-detected locale by the browser or the specifed locale by `echarts.init` function; + * It supports the default built-in locale name: EN, ZH/CN; or ant other registed locale name; or customized array + * index 0 always means Jan */ - nameMap?: 'en' | 'cn' | string[] + nameMap?: 'en' | 'cn' | 'zh' | string[] formatter?: string | ((params: CalendarMonthLabelFormatterCallbackParams) => string) } @@ -214,7 +218,6 @@ class CalendarModel extends ComponentModel { // start end position: 'start', margin: '50%', // 50% of cellSize - nameMap: 'en', color: '#000' }, @@ -229,8 +232,6 @@ class CalendarModel extends ComponentModel { // center or left align: 'center', - // cn en [] - nameMap: 'en', formatter: null, color: '#000' }, diff --git a/test/calendar-week.html b/test/calendar-week.html index cfb8dd2e6b..7b234606a8 100644 --- a/test/calendar-week.html +++ b/test/calendar-week.html @@ -62,9 +62,17 @@ } return datas; } - require(['echarts'], function (echarts) { - - var chart = echarts.init(document.getElementById('main')); + require([ + 'echarts', + 'i18n/langES-obj', + 'i18n/langJA-obj' + ], function (echarts, langES, langJA) { + echarts.registerLocale('ES', langES); + echarts.registerLocale('JA', langJA); + + var chart = echarts.init(document.getElementById('main'), null, { + // locale: 'ES' + }); chart.setOption({ tooltip: { @@ -82,7 +90,8 @@ calendar: [ { dayLabel: { - position: 'start' + position: 'start', + nameMap: 'JA' }, range: '2017-01' }, @@ -96,7 +105,7 @@ { dayLabel: { position: 'start', - nameMap: 'cn' + nameMap: 'en' }, left: 550, range: '2017-03' From d5d9ac9b0f7799b9a85cee8a70ccc76ee04f1595 Mon Sep 17 00:00:00 2001 From: plainheart Date: Mon, 25 Oct 2021 11:59:36 +0800 Subject: [PATCH 2/5] refactor(calenlar-i18n): 1) use the capital of `dayOfWeekAbbr` if `dayOfWeekShort` doesn't exist in the locale file. 2) `nameMap` can be any registered locale name (case-sensitive). --- src/component/calendar/CalendarView.ts | 35 +++++++++++--------------- src/coord/calendar/CalendarModel.ts | 8 +++--- src/i18n/langEN.ts | 3 +++ 3 files changed, 21 insertions(+), 25 deletions(-) diff --git a/src/component/calendar/CalendarView.ts b/src/component/calendar/CalendarView.ts index 547f524e8e..f71a79642e 100644 --- a/src/component/calendar/CalendarView.ts +++ b/src/component/calendar/CalendarView.ts @@ -17,7 +17,7 @@ * under the License. */ -import * as zrUtil from 'zrender/src/core/util'; +import { isString, extend, map } from 'zrender/src/core/util'; import * as graphic from '../../util/graphic'; import {createTextStyle} from '../../label/labelStyle'; import { formatTplSimple } from '../../util/format'; @@ -407,15 +407,13 @@ class CalendarView extends ComponentView { const termPoints = [this._tlpoints, this._blpoints]; - if (!nameMap || zrUtil.isString(nameMap)) { + if (!nameMap || isString(nameMap)) { if (nameMap) { - const nameMapUpperCase = (nameMap as string).toUpperCase(); - localeModel = getLocaleModel(nameMapUpperCase === 'CN' ? 'ZH' : nameMapUpperCase) || localeModel; + // case-sensitive + localeModel = getLocaleModel(nameMap as string) || localeModel; } // PENDING // for ZH locale, original form is `一月` but current form is `1月` - // Consider adding a new configuration for each locale? - // For example, `time.monthShortcut` or `calendar.month` nameMap = localeModel.get(['time', 'monthAbbr']) || []; } @@ -448,7 +446,7 @@ class CalendarView extends ComponentView { const monthText = new graphic.Text({ z2: 30, - style: zrUtil.extend( + style: extend( createTextStyle(monthLabel, {text: content}), this._monthTextPositionControl(tmp, isCenter, orient, pos, margin) ) @@ -508,21 +506,16 @@ class CalendarView extends ComponentView { let margin = dayLabel.get('margin'); const firstDayOfWeek = coordSys.getFirstDayOfWeek(); - if (!nameMap || zrUtil.isString(nameMap)) { + if (!nameMap || isString(nameMap)) { if (nameMap) { - const nameMapUpperCase = (nameMap as string).toUpperCase(); - localeModel = getLocaleModel(nameMapUpperCase === 'CN' ? 'ZH' : nameMapUpperCase) || localeModel; + // case-sensitive + localeModel = getLocaleModel(nameMap as string) || localeModel; } - // PENDING: - // Current each word of `dayOfWeekAbbr` in `EN` locale is a bit long. - // Use the capital as shortcut. - // ['Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat'] - // ↓ - // ['S', 'M', 'T', 'W', 'T', 'F', 'S'] - // Or consider adding a new configuration for each locale? - // For example, `time.dayOfWeekShortcut` or `calendar.dayOfWeek` - nameMap = zrUtil.map( - localeModel.get(['time', 'dayOfWeekAbbr']) || [], + debugger + // Use the capital of `dayOfWeekAbbr` if `dayOfWeekShort` doesn't exist in the locale file. + const dayOfWeekShort = localeModel.get(['time', 'dayOfWeekShort']); + nameMap = dayOfWeekShort || map( + localeModel.get(['time', 'dayOfWeekAbbr']), val => val[0] ); } @@ -549,7 +542,7 @@ class CalendarView extends ComponentView { day = Math.abs((i + firstDayOfWeek) % 7); const weekText = new graphic.Text({ z2: 30, - style: zrUtil.extend( + style: extend( createTextStyle(dayLabel, {text: nameMap[day]}), this._weekTextPositionControl(point, orient, pos, margin, cellSize) ) diff --git a/src/coord/calendar/CalendarModel.ts b/src/coord/calendar/CalendarModel.ts index 8930b9c9d6..8b98191d88 100644 --- a/src/coord/calendar/CalendarModel.ts +++ b/src/coord/calendar/CalendarModel.ts @@ -107,10 +107,10 @@ export interface CalendarOption extends ComponentOption, BoxLayoutOptionMixin { /** * Week text content * defaults to auto-detected locale by the browser or the specifed locale by `echarts.init` function; - * It supports the default built-in locale name: EN, ZH/CN; or ant other registed locale name; or customized array + * It supports any registered locale name (case-sensitive) or customized array * index 0 always means Sunday */ - nameMap?: 'en' | 'cn' | 'zh' | string[] + nameMap?: string | string[] } monthLabel?: Omit & { @@ -127,10 +127,10 @@ export interface CalendarOption extends ComponentOption, BoxLayoutOptionMixin { /** * Month text content * defaults to auto-detected locale by the browser or the specifed locale by `echarts.init` function; - * It supports the default built-in locale name: EN, ZH/CN; or ant other registed locale name; or customized array + * It supports any registered locale name (case-sensitive) or customized array * index 0 always means Jan */ - nameMap?: 'en' | 'cn' | 'zh' | string[] + nameMap?: string | string[] formatter?: string | ((params: CalendarMonthLabelFormatterCallbackParams) => string) } diff --git a/src/i18n/langEN.ts b/src/i18n/langEN.ts index 311c6a22af..eded099a1b 100644 --- a/src/i18n/langEN.ts +++ b/src/i18n/langEN.ts @@ -36,6 +36,9 @@ export default { ], dayOfWeekAbbr: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' + ], + dayOfWeekShort: [ + 'S', 'M', 'T', 'W', 'T', 'F', 'S' ] }, legend: { From f28a405f9af942fc89ef16204a279456f54a7aca Mon Sep 17 00:00:00 2001 From: plainheart Date: Mon, 25 Oct 2021 12:08:46 +0800 Subject: [PATCH 3/5] chore(calendar): remove dev code. --- src/component/calendar/CalendarView.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/component/calendar/CalendarView.ts b/src/component/calendar/CalendarView.ts index f71a79642e..560790decd 100644 --- a/src/component/calendar/CalendarView.ts +++ b/src/component/calendar/CalendarView.ts @@ -511,7 +511,6 @@ class CalendarView extends ComponentView { // case-sensitive localeModel = getLocaleModel(nameMap as string) || localeModel; } - debugger // Use the capital of `dayOfWeekAbbr` if `dayOfWeekShort` doesn't exist in the locale file. const dayOfWeekShort = localeModel.get(['time', 'dayOfWeekShort']); nameMap = dayOfWeekShort || map( From 796c987d12748af16246dd9c1a1105f006a7c86e Mon Sep 17 00:00:00 2001 From: plainheart Date: Mon, 25 Oct 2021 15:01:09 +0800 Subject: [PATCH 4/5] fix(calendar-i18n): remove `dayOfWeekShort` configuration from `en` locale. --- src/component/calendar/CalendarView.ts | 4 +-- src/i18n/langEN.ts | 3 --- test/calendar-week.html | 35 +++++++++++++++++++------- 3 files changed, 28 insertions(+), 14 deletions(-) diff --git a/src/component/calendar/CalendarView.ts b/src/component/calendar/CalendarView.ts index 560790decd..1eecd0bcc1 100644 --- a/src/component/calendar/CalendarView.ts +++ b/src/component/calendar/CalendarView.ts @@ -511,8 +511,8 @@ class CalendarView extends ComponentView { // case-sensitive localeModel = getLocaleModel(nameMap as string) || localeModel; } - // Use the capital of `dayOfWeekAbbr` if `dayOfWeekShort` doesn't exist in the locale file. - const dayOfWeekShort = localeModel.get(['time', 'dayOfWeekShort']); + // Use the first letter of `dayOfWeekAbbr` if `dayOfWeekShort` doesn't exist in the locale file + const dayOfWeekShort = localeModel.get(['time', 'dayOfWeekShort' as any]); nameMap = dayOfWeekShort || map( localeModel.get(['time', 'dayOfWeekAbbr']), val => val[0] diff --git a/src/i18n/langEN.ts b/src/i18n/langEN.ts index eded099a1b..311c6a22af 100644 --- a/src/i18n/langEN.ts +++ b/src/i18n/langEN.ts @@ -36,9 +36,6 @@ export default { ], dayOfWeekAbbr: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' - ], - dayOfWeekShort: [ - 'S', 'M', 'T', 'W', 'T', 'F', 'S' ] }, legend: { diff --git a/test/calendar-week.html b/test/calendar-week.html index 7b234606a8..f756923520 100644 --- a/test/calendar-week.html +++ b/test/calendar-week.html @@ -65,13 +65,21 @@ require([ 'echarts', 'i18n/langES-obj', - 'i18n/langJA-obj' - ], function (echarts, langES, langJA) { + 'i18n/langJA-obj', + 'i18n/langTH-obj', + 'i18n/langFR-obj', + 'i18n/langFI-obj', + 'i18n/langRU-obj' + ], function (echarts, langES, langJA, langTH, langFR, langFI, langRU) { echarts.registerLocale('ES', langES); echarts.registerLocale('JA', langJA); + echarts.registerLocale('TH', langTH); + echarts.registerLocale('FR', langFR); + echarts.registerLocale('FI', langFI); + echarts.registerLocale('RU', langRU); var chart = echarts.init(document.getElementById('main'), null, { - // locale: 'ES' + locale: 'RU' }); chart.setOption({ @@ -105,7 +113,7 @@ { dayLabel: { position: 'start', - nameMap: 'en' + nameMap: 'ES' }, left: 550, range: '2017-03' @@ -113,7 +121,7 @@ { dayLabel: { firstDay: 1, - nameMap: 'cn' + nameMap: 'EN' }, left: 750, range: '2017-04' @@ -121,7 +129,8 @@ { dayLabel: { - position: 'start' + position: 'start', + nameMap: 'TH' }, top: 320, orient: 'vertical', @@ -129,7 +138,8 @@ }, { dayLabel: { - position: 'end' + position: 'end', + nameMap: 'FR' }, top: 320, left: 300, @@ -150,10 +160,13 @@ yearLabel: { margin: 0 }, + monthLabel: { + nameMap: 'EN' + }, dayLabel: { margin: 10, position: 'end', - nameMap: 'cn', + nameMap: 'FI', firstDay: 1 }, top: 320, @@ -181,8 +194,12 @@ range: ['2017-12-01', '2018-01-31'] }, { + monthLabel: { + nameMap: 'ZH' + }, dayLabel: { - firstDay: 1 + firstDay: 1, + nameMap: 'RU' }, top: 500, range: '2017' From 657752fe56e134f6c015583dc7f77c5e9f554b8b Mon Sep 17 00:00:00 2001 From: plainheart Date: Mon, 25 Oct 2021 16:32:45 +0800 Subject: [PATCH 5/5] chore(calendar): tweak comment. --- src/coord/calendar/CalendarModel.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/coord/calendar/CalendarModel.ts b/src/coord/calendar/CalendarModel.ts index 8b98191d88..9e49cd0b72 100644 --- a/src/coord/calendar/CalendarModel.ts +++ b/src/coord/calendar/CalendarModel.ts @@ -106,9 +106,10 @@ export interface CalendarOption extends ComponentOption, BoxLayoutOptionMixin { /** * Week text content - * defaults to auto-detected locale by the browser or the specifed locale by `echarts.init` function; - * It supports any registered locale name (case-sensitive) or customized array - * index 0 always means Sunday + * + * defaults to auto-detected locale by the browser or the specified locale by `echarts.init` function. + * It supports any registered locale name (case-sensitive) or customized array. + * index 0 always means Sunday. */ nameMap?: string | string[] } @@ -126,9 +127,10 @@ export interface CalendarOption extends ComponentOption, BoxLayoutOptionMixin { /** * Month text content - * defaults to auto-detected locale by the browser or the specifed locale by `echarts.init` function; - * It supports any registered locale name (case-sensitive) or customized array - * index 0 always means Jan + * + * defaults to auto-detected locale by the browser or the specified locale by `echarts.init` function. + * It supports any registered locale name (case-sensitive) or customized array. + * index 0 always means Jan. */ nameMap?: string | string[]