451 lines
13 KiB
JavaScript
451 lines
13 KiB
JavaScript
|
|
||
|
/*
|
||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||
|
* or more contributor license agreements. See the NOTICE file
|
||
|
* distributed with this work for additional information
|
||
|
* regarding copyright ownership. The ASF licenses this file
|
||
|
* to you under the Apache License, Version 2.0 (the
|
||
|
* "License"); you may not use this file except in compliance
|
||
|
* with the License. You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing,
|
||
|
* software distributed under the License is distributed on an
|
||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
|
* KIND, either express or implied. See the License for the
|
||
|
* specific language governing permissions and limitations
|
||
|
* under the License.
|
||
|
*/
|
||
|
|
||
|
var echarts = require("../../echarts");
|
||
|
|
||
|
var zrUtil = require("zrender/lib/core/util");
|
||
|
|
||
|
var graphic = require("../../util/graphic");
|
||
|
|
||
|
var formatUtil = require("../../util/format");
|
||
|
|
||
|
var numberUtil = require("../../util/number");
|
||
|
|
||
|
/*
|
||
|
* Licensed to the Apache Software Foundation (ASF) under one
|
||
|
* or more contributor license agreements. See the NOTICE file
|
||
|
* distributed with this work for additional information
|
||
|
* regarding copyright ownership. The ASF licenses this file
|
||
|
* to you under the Apache License, Version 2.0 (the
|
||
|
* "License"); you may not use this file except in compliance
|
||
|
* with the License. You may obtain a copy of the License at
|
||
|
*
|
||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||
|
*
|
||
|
* Unless required by applicable law or agreed to in writing,
|
||
|
* software distributed under the License is distributed on an
|
||
|
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||
|
* KIND, either express or implied. See the License for the
|
||
|
* specific language governing permissions and limitations
|
||
|
* under the License.
|
||
|
*/
|
||
|
var MONTH_TEXT = {
|
||
|
EN: ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'],
|
||
|
CN: ['一月', '二月', '三月', '四月', '五月', '六月', '七月', '八月', '九月', '十月', '十一月', '十二月']
|
||
|
};
|
||
|
var WEEK_TEXT = {
|
||
|
EN: ['S', 'M', 'T', 'W', 'T', 'F', 'S'],
|
||
|
CN: ['日', '一', '二', '三', '四', '五', '六']
|
||
|
};
|
||
|
|
||
|
var _default = echarts.extendComponentView({
|
||
|
type: 'calendar',
|
||
|
|
||
|
/**
|
||
|
* top/left line points
|
||
|
* @private
|
||
|
*/
|
||
|
_tlpoints: null,
|
||
|
|
||
|
/**
|
||
|
* bottom/right line points
|
||
|
* @private
|
||
|
*/
|
||
|
_blpoints: null,
|
||
|
|
||
|
/**
|
||
|
* first day of month
|
||
|
* @private
|
||
|
*/
|
||
|
_firstDayOfMonth: null,
|
||
|
|
||
|
/**
|
||
|
* first day point of month
|
||
|
* @private
|
||
|
*/
|
||
|
_firstDayPoints: null,
|
||
|
render: function (calendarModel, ecModel, api) {
|
||
|
var group = this.group;
|
||
|
group.removeAll();
|
||
|
var coordSys = calendarModel.coordinateSystem; // range info
|
||
|
|
||
|
var rangeData = coordSys.getRangeInfo();
|
||
|
var orient = coordSys.getOrient();
|
||
|
|
||
|
this._renderDayRect(calendarModel, rangeData, group); // _renderLines must be called prior to following function
|
||
|
|
||
|
|
||
|
this._renderLines(calendarModel, rangeData, orient, group);
|
||
|
|
||
|
this._renderYearText(calendarModel, rangeData, orient, group);
|
||
|
|
||
|
this._renderMonthText(calendarModel, orient, group);
|
||
|
|
||
|
this._renderWeekText(calendarModel, rangeData, orient, group);
|
||
|
},
|
||
|
// render day rect
|
||
|
_renderDayRect: function (calendarModel, rangeData, group) {
|
||
|
var coordSys = calendarModel.coordinateSystem;
|
||
|
var itemRectStyleModel = calendarModel.getModel('itemStyle').getItemStyle();
|
||
|
var sw = coordSys.getCellWidth();
|
||
|
var sh = coordSys.getCellHeight();
|
||
|
|
||
|
for (var i = rangeData.start.time; i <= rangeData.end.time; i = coordSys.getNextNDay(i, 1).time) {
|
||
|
var point = coordSys.dataToRect([i], false).tl; // every rect
|
||
|
|
||
|
var rect = new graphic.Rect({
|
||
|
shape: {
|
||
|
x: point[0],
|
||
|
y: point[1],
|
||
|
width: sw,
|
||
|
height: sh
|
||
|
},
|
||
|
cursor: 'default',
|
||
|
style: itemRectStyleModel
|
||
|
});
|
||
|
group.add(rect);
|
||
|
}
|
||
|
},
|
||
|
// render separate line
|
||
|
_renderLines: function (calendarModel, rangeData, orient, group) {
|
||
|
var self = this;
|
||
|
var coordSys = calendarModel.coordinateSystem;
|
||
|
var lineStyleModel = calendarModel.getModel('splitLine.lineStyle').getLineStyle();
|
||
|
var show = calendarModel.get('splitLine.show');
|
||
|
var lineWidth = lineStyleModel.lineWidth;
|
||
|
this._tlpoints = [];
|
||
|
this._blpoints = [];
|
||
|
this._firstDayOfMonth = [];
|
||
|
this._firstDayPoints = [];
|
||
|
var firstDay = rangeData.start;
|
||
|
|
||
|
for (var i = 0; firstDay.time <= rangeData.end.time; i++) {
|
||
|
addPoints(firstDay.formatedDate);
|
||
|
|
||
|
if (i === 0) {
|
||
|
firstDay = coordSys.getDateInfo(rangeData.start.y + '-' + rangeData.start.m);
|
||
|
}
|
||
|
|
||
|
var date = firstDay.date;
|
||
|
date.setMonth(date.getMonth() + 1);
|
||
|
firstDay = coordSys.getDateInfo(date);
|
||
|
}
|
||
|
|
||
|
addPoints(coordSys.getNextNDay(rangeData.end.time, 1).formatedDate);
|
||
|
|
||
|
function addPoints(date) {
|
||
|
self._firstDayOfMonth.push(coordSys.getDateInfo(date));
|
||
|
|
||
|
self._firstDayPoints.push(coordSys.dataToRect([date], false).tl);
|
||
|
|
||
|
var points = self._getLinePointsOfOneWeek(calendarModel, date, orient);
|
||
|
|
||
|
self._tlpoints.push(points[0]);
|
||
|
|
||
|
self._blpoints.push(points[points.length - 1]);
|
||
|
|
||
|
show && self._drawSplitline(points, lineStyleModel, group);
|
||
|
} // render top/left line
|
||
|
|
||
|
|
||
|
show && this._drawSplitline(self._getEdgesPoints(self._tlpoints, lineWidth, orient), lineStyleModel, group); // render bottom/right line
|
||
|
|
||
|
show && this._drawSplitline(self._getEdgesPoints(self._blpoints, lineWidth, orient), lineStyleModel, group);
|
||
|
},
|
||
|
// get points at both ends
|
||
|
_getEdgesPoints: function (points, lineWidth, orient) {
|
||
|
var rs = [points[0].slice(), points[points.length - 1].slice()];
|
||
|
var idx = orient === 'horizontal' ? 0 : 1; // both ends of the line are extend half lineWidth
|
||
|
|
||
|
rs[0][idx] = rs[0][idx] - lineWidth / 2;
|
||
|
rs[1][idx] = rs[1][idx] + lineWidth / 2;
|
||
|
return rs;
|
||
|
},
|
||
|
// render split line
|
||
|
_drawSplitline: function (points, lineStyleModel, group) {
|
||
|
var poyline = new graphic.Polyline({
|
||
|
z2: 20,
|
||
|
shape: {
|
||
|
points: points
|
||
|
},
|
||
|
style: lineStyleModel
|
||
|
});
|
||
|
group.add(poyline);
|
||
|
},
|
||
|
// render month line of one week points
|
||
|
_getLinePointsOfOneWeek: function (calendarModel, date, orient) {
|
||
|
var coordSys = calendarModel.coordinateSystem;
|
||
|
date = coordSys.getDateInfo(date);
|
||
|
var points = [];
|
||
|
|
||
|
for (var i = 0; i < 7; i++) {
|
||
|
var tmpD = coordSys.getNextNDay(date.time, i);
|
||
|
var point = coordSys.dataToRect([tmpD.time], false);
|
||
|
points[2 * tmpD.day] = point.tl;
|
||
|
points[2 * tmpD.day + 1] = point[orient === 'horizontal' ? 'bl' : 'tr'];
|
||
|
}
|
||
|
|
||
|
return points;
|
||
|
},
|
||
|
_formatterLabel: function (formatter, params) {
|
||
|
if (typeof formatter === 'string' && formatter) {
|
||
|
return formatUtil.formatTplSimple(formatter, params);
|
||
|
}
|
||
|
|
||
|
if (typeof formatter === 'function') {
|
||
|
return formatter(params);
|
||
|
}
|
||
|
|
||
|
return params.nameMap;
|
||
|
},
|
||
|
_yearTextPositionControl: function (textEl, point, orient, position, margin) {
|
||
|
point = point.slice();
|
||
|
var aligns = ['center', 'bottom'];
|
||
|
|
||
|
if (position === 'bottom') {
|
||
|
point[1] += margin;
|
||
|
aligns = ['center', 'top'];
|
||
|
} else if (position === 'left') {
|
||
|
point[0] -= margin;
|
||
|
} else if (position === 'right') {
|
||
|
point[0] += margin;
|
||
|
aligns = ['center', 'top'];
|
||
|
} else {
|
||
|
// top
|
||
|
point[1] -= margin;
|
||
|
}
|
||
|
|
||
|
var rotate = 0;
|
||
|
|
||
|
if (position === 'left' || position === 'right') {
|
||
|
rotate = Math.PI / 2;
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
rotation: rotate,
|
||
|
position: point,
|
||
|
style: {
|
||
|
textAlign: aligns[0],
|
||
|
textVerticalAlign: aligns[1]
|
||
|
}
|
||
|
};
|
||
|
},
|
||
|
// render year
|
||
|
_renderYearText: function (calendarModel, rangeData, orient, group) {
|
||
|
var yearLabel = calendarModel.getModel('yearLabel');
|
||
|
|
||
|
if (!yearLabel.get('show')) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var margin = yearLabel.get('margin');
|
||
|
var pos = yearLabel.get('position');
|
||
|
|
||
|
if (!pos) {
|
||
|
pos = orient !== 'horizontal' ? 'top' : 'left';
|
||
|
}
|
||
|
|
||
|
var points = [this._tlpoints[this._tlpoints.length - 1], this._blpoints[0]];
|
||
|
var xc = (points[0][0] + points[1][0]) / 2;
|
||
|
var yc = (points[0][1] + points[1][1]) / 2;
|
||
|
var idx = orient === 'horizontal' ? 0 : 1;
|
||
|
var posPoints = {
|
||
|
top: [xc, points[idx][1]],
|
||
|
bottom: [xc, points[1 - idx][1]],
|
||
|
left: [points[1 - idx][0], yc],
|
||
|
right: [points[idx][0], yc]
|
||
|
};
|
||
|
var name = rangeData.start.y;
|
||
|
|
||
|
if (+rangeData.end.y > +rangeData.start.y) {
|
||
|
name = name + '-' + rangeData.end.y;
|
||
|
}
|
||
|
|
||
|
var formatter = yearLabel.get('formatter');
|
||
|
var params = {
|
||
|
start: rangeData.start.y,
|
||
|
end: rangeData.end.y,
|
||
|
nameMap: name
|
||
|
};
|
||
|
|
||
|
var content = this._formatterLabel(formatter, params);
|
||
|
|
||
|
var yearText = new graphic.Text({
|
||
|
z2: 30
|
||
|
});
|
||
|
graphic.setTextStyle(yearText.style, yearLabel, {
|
||
|
text: content
|
||
|
}), yearText.attr(this._yearTextPositionControl(yearText, posPoints[pos], orient, pos, margin));
|
||
|
group.add(yearText);
|
||
|
},
|
||
|
_monthTextPositionControl: function (point, isCenter, orient, position, margin) {
|
||
|
var align = 'left';
|
||
|
var vAlign = 'top';
|
||
|
var x = point[0];
|
||
|
var y = point[1];
|
||
|
|
||
|
if (orient === 'horizontal') {
|
||
|
y = y + margin;
|
||
|
|
||
|
if (isCenter) {
|
||
|
align = 'center';
|
||
|
}
|
||
|
|
||
|
if (position === 'start') {
|
||
|
vAlign = 'bottom';
|
||
|
}
|
||
|
} else {
|
||
|
x = x + margin;
|
||
|
|
||
|
if (isCenter) {
|
||
|
vAlign = 'middle';
|
||
|
}
|
||
|
|
||
|
if (position === 'start') {
|
||
|
align = 'right';
|
||
|
}
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
x: x,
|
||
|
y: y,
|
||
|
textAlign: align,
|
||
|
textVerticalAlign: vAlign
|
||
|
};
|
||
|
},
|
||
|
// render month and year text
|
||
|
_renderMonthText: function (calendarModel, orient, group) {
|
||
|
var monthLabel = calendarModel.getModel('monthLabel');
|
||
|
|
||
|
if (!monthLabel.get('show')) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var nameMap = monthLabel.get('nameMap');
|
||
|
var margin = monthLabel.get('margin');
|
||
|
var pos = monthLabel.get('position');
|
||
|
var align = monthLabel.get('align');
|
||
|
var termPoints = [this._tlpoints, this._blpoints];
|
||
|
|
||
|
if (zrUtil.isString(nameMap)) {
|
||
|
nameMap = MONTH_TEXT[nameMap.toUpperCase()] || [];
|
||
|
}
|
||
|
|
||
|
var idx = pos === 'start' ? 0 : 1;
|
||
|
var axis = orient === 'horizontal' ? 0 : 1;
|
||
|
margin = pos === 'start' ? -margin : margin;
|
||
|
var isCenter = align === 'center';
|
||
|
|
||
|
for (var i = 0; i < termPoints[idx].length - 1; i++) {
|
||
|
var tmp = termPoints[idx][i].slice();
|
||
|
var firstDay = this._firstDayOfMonth[i];
|
||
|
|
||
|
if (isCenter) {
|
||
|
var firstDayPoints = this._firstDayPoints[i];
|
||
|
tmp[axis] = (firstDayPoints[axis] + termPoints[0][i + 1][axis]) / 2;
|
||
|
}
|
||
|
|
||
|
var formatter = monthLabel.get('formatter');
|
||
|
var name = nameMap[+firstDay.m - 1];
|
||
|
var params = {
|
||
|
yyyy: firstDay.y,
|
||
|
yy: (firstDay.y + '').slice(2),
|
||
|
MM: firstDay.m,
|
||
|
M: +firstDay.m,
|
||
|
nameMap: name
|
||
|
};
|
||
|
|
||
|
var content = this._formatterLabel(formatter, params);
|
||
|
|
||
|
var monthText = new graphic.Text({
|
||
|
z2: 30
|
||
|
});
|
||
|
zrUtil.extend(graphic.setTextStyle(monthText.style, monthLabel, {
|
||
|
text: content
|
||
|
}), this._monthTextPositionControl(tmp, isCenter, orient, pos, margin));
|
||
|
group.add(monthText);
|
||
|
}
|
||
|
},
|
||
|
_weekTextPositionControl: function (point, orient, position, margin, cellSize) {
|
||
|
var align = 'center';
|
||
|
var vAlign = 'middle';
|
||
|
var x = point[0];
|
||
|
var y = point[1];
|
||
|
var isStart = position === 'start';
|
||
|
|
||
|
if (orient === 'horizontal') {
|
||
|
x = x + margin + (isStart ? 1 : -1) * cellSize[0] / 2;
|
||
|
align = isStart ? 'right' : 'left';
|
||
|
} else {
|
||
|
y = y + margin + (isStart ? 1 : -1) * cellSize[1] / 2;
|
||
|
vAlign = isStart ? 'bottom' : 'top';
|
||
|
}
|
||
|
|
||
|
return {
|
||
|
x: x,
|
||
|
y: y,
|
||
|
textAlign: align,
|
||
|
textVerticalAlign: vAlign
|
||
|
};
|
||
|
},
|
||
|
// render weeks
|
||
|
_renderWeekText: function (calendarModel, rangeData, orient, group) {
|
||
|
var dayLabel = calendarModel.getModel('dayLabel');
|
||
|
|
||
|
if (!dayLabel.get('show')) {
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
var coordSys = calendarModel.coordinateSystem;
|
||
|
var pos = dayLabel.get('position');
|
||
|
var nameMap = dayLabel.get('nameMap');
|
||
|
var margin = dayLabel.get('margin');
|
||
|
var firstDayOfWeek = coordSys.getFirstDayOfWeek();
|
||
|
|
||
|
if (zrUtil.isString(nameMap)) {
|
||
|
nameMap = WEEK_TEXT[nameMap.toUpperCase()] || [];
|
||
|
}
|
||
|
|
||
|
var start = coordSys.getNextNDay(rangeData.end.time, 7 - rangeData.lweek).time;
|
||
|
var cellSize = [coordSys.getCellWidth(), coordSys.getCellHeight()];
|
||
|
margin = numberUtil.parsePercent(margin, cellSize[orient === 'horizontal' ? 0 : 1]);
|
||
|
|
||
|
if (pos === 'start') {
|
||
|
start = coordSys.getNextNDay(rangeData.start.time, -(7 + rangeData.fweek)).time;
|
||
|
margin = -margin;
|
||
|
}
|
||
|
|
||
|
for (var i = 0; i < 7; i++) {
|
||
|
var tmpD = coordSys.getNextNDay(start, i);
|
||
|
var point = coordSys.dataToRect([tmpD.time], false).center;
|
||
|
var day = i;
|
||
|
day = Math.abs((i + firstDayOfWeek) % 7);
|
||
|
var weekText = new graphic.Text({
|
||
|
z2: 30
|
||
|
});
|
||
|
zrUtil.extend(graphic.setTextStyle(weekText.style, dayLabel, {
|
||
|
text: nameMap[day]
|
||
|
}), this._weekTextPositionControl(point, orient, pos, margin, cellSize));
|
||
|
group.add(weekText);
|
||
|
}
|
||
|
}
|
||
|
});
|
||
|
|
||
|
module.exports = _default;
|