diff --git a/src/component/calendar/CalendarView.ts b/src/component/calendar/CalendarView.ts index d1e15972ec..1eecd0bcc1 100644 --- a/src/component/calendar/CalendarView.ts +++ b/src/component/calendar/CalendarView.ts @@ -17,39 +17,21 @@ * 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 * 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,14 @@ class CalendarView extends ComponentView { const termPoints = [this._tlpoints, this._blpoints]; - if (zrUtil.isString(nameMap)) { - nameMap = MONTH_TEXT[nameMap.toUpperCase() as 'CN' | 'EN'] || []; + if (!nameMap || isString(nameMap)) { + if (nameMap) { + // case-sensitive + localeModel = getLocaleModel(nameMap as string) || localeModel; + } + // PENDING + // for ZH locale, original form is `一月` but current form is `1月` + nameMap = localeModel.get(['time', 'monthAbbr']) || []; } const idx = pos === 'start' ? 0 : 1; @@ -450,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) ) @@ -493,6 +489,7 @@ class CalendarView extends ComponentView { // render weeks _renderWeekText( calendarModel: CalendarModel, + localeModel: Model, rangeData: CalendarParsedDateRangeInfo, orient: LayoutOrient, group: graphic.Group @@ -509,8 +506,17 @@ 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 || isString(nameMap)) { + if (nameMap) { + // case-sensitive + localeModel = getLocaleModel(nameMap as string) || localeModel; + } + // 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] + ); } let start = coordSys.getNextNDay( @@ -518,7 +524,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( @@ -535,7 +541,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) ) @@ -546,4 +552,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..9e49cd0b72 100644 --- a/src/coord/calendar/CalendarModel.ts +++ b/src/coord/calendar/CalendarModel.ts @@ -105,11 +105,13 @@ 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 specified locale by `echarts.init` function. + * It supports any registered locale name (case-sensitive) or customized array. + * index 0 always means Sunday. */ - nameMap?: 'en' | 'cn' | string[] + nameMap?: string | string[] } monthLabel?: Omit & { @@ -124,9 +126,13 @@ 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 specified locale by `echarts.init` function. + * It supports any registered locale name (case-sensitive) or customized array. + * index 0 always means Jan. */ - nameMap?: 'en' | 'cn' | string[] + nameMap?: string | string[] formatter?: string | ((params: CalendarMonthLabelFormatterCallbackParams) => string) } @@ -214,7 +220,6 @@ class CalendarModel extends ComponentModel { // start end position: 'start', margin: '50%', // 50% of cellSize - nameMap: 'en', color: '#000' }, @@ -229,8 +234,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..f756923520 100644 --- a/test/calendar-week.html +++ b/test/calendar-week.html @@ -62,9 +62,25 @@ } return datas; } - require(['echarts'], function (echarts) { + require([ + 'echarts', + 'i18n/langES-obj', + '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')); + var chart = echarts.init(document.getElementById('main'), null, { + locale: 'RU' + }); chart.setOption({ tooltip: { @@ -82,7 +98,8 @@ calendar: [ { dayLabel: { - position: 'start' + position: 'start', + nameMap: 'JA' }, range: '2017-01' }, @@ -96,7 +113,7 @@ { dayLabel: { position: 'start', - nameMap: 'cn' + nameMap: 'ES' }, left: 550, range: '2017-03' @@ -104,7 +121,7 @@ { dayLabel: { firstDay: 1, - nameMap: 'cn' + nameMap: 'EN' }, left: 750, range: '2017-04' @@ -112,7 +129,8 @@ { dayLabel: { - position: 'start' + position: 'start', + nameMap: 'TH' }, top: 320, orient: 'vertical', @@ -120,7 +138,8 @@ }, { dayLabel: { - position: 'end' + position: 'end', + nameMap: 'FR' }, top: 320, left: 300, @@ -141,10 +160,13 @@ yearLabel: { margin: 0 }, + monthLabel: { + nameMap: 'EN' + }, dayLabel: { margin: 10, position: 'end', - nameMap: 'cn', + nameMap: 'FI', firstDay: 1 }, top: 320, @@ -172,8 +194,12 @@ range: ['2017-12-01', '2018-01-31'] }, { + monthLabel: { + nameMap: 'ZH' + }, dayLabel: { - firstDay: 1 + firstDay: 1, + nameMap: 'RU' }, top: 500, range: '2017'