462 lines
16 KiB
JavaScript
462 lines
16 KiB
JavaScript
"use strict";
|
|
|
|
Object.defineProperty(exports, "__esModule", {
|
|
value: true
|
|
});
|
|
exports.default = void 0;
|
|
var _matrixUtil = require("@antv/matrix-util");
|
|
var _util = require("@antv/util");
|
|
var _timeBarTooltip = _interopRequireDefault(require("./timeBarTooltip"));
|
|
var _controllerBtn = _interopRequireDefault(require("./controllerBtn"));
|
|
var _constant = require("./constant");
|
|
function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
|
|
var __assign = void 0 && (void 0).__assign || function () {
|
|
__assign = Object.assign || function (t) {
|
|
for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
s = arguments[i];
|
|
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
}
|
|
return t;
|
|
};
|
|
return __assign.apply(this, arguments);
|
|
};
|
|
/**
|
|
* 基于 G 的刻度时间轴组件
|
|
*/
|
|
|
|
var transform = _matrixUtil.ext.transform;
|
|
var DEFAULT_SELECTEDTICK_STYLE = {
|
|
fill: '#5B8FF9'
|
|
};
|
|
var DEFAULT_UNSELECTEDTICK_STYLE = {
|
|
fill: '#e6e8e9'
|
|
};
|
|
var TimeBarSlice = /** @class */function () {
|
|
function TimeBarSlice(cfgs) {
|
|
this.frameCount = 0;
|
|
this.fontFamily = 'Arial, sans-serif';
|
|
var graph = cfgs.graph,
|
|
canvas = cfgs.canvas,
|
|
group = cfgs.group,
|
|
width = cfgs.width,
|
|
height = cfgs.height,
|
|
padding = cfgs.padding,
|
|
data = cfgs.data,
|
|
start = cfgs.start,
|
|
end = cfgs.end,
|
|
_a = cfgs.x,
|
|
x = _a === void 0 ? 0 : _a,
|
|
_b = cfgs.y,
|
|
y = _b === void 0 ? 0 : _b,
|
|
tickLabelFormatter = cfgs.tickLabelFormatter,
|
|
_c = cfgs.selectedTickStyle,
|
|
selectedTickStyle = _c === void 0 ? DEFAULT_SELECTEDTICK_STYLE : _c,
|
|
_d = cfgs.unselectedTickStyle,
|
|
unselectedTickStyle = _d === void 0 ? DEFAULT_UNSELECTEDTICK_STYLE : _d,
|
|
tooltipBackgroundColor = cfgs.tooltipBackgroundColor,
|
|
tooltipFomatter = cfgs.tooltipFomatter,
|
|
tickLabelStyle = cfgs.tickLabelStyle,
|
|
_e = cfgs.controllerCfg,
|
|
controllerCfg = _e === void 0 ? {
|
|
speed: 1
|
|
} : _e;
|
|
this.graph = graph;
|
|
this.group = group;
|
|
this.sliceGroup = group.addGroup({
|
|
name: 'slice-group'
|
|
});
|
|
this.canvas = canvas;
|
|
this.width = width;
|
|
this.height = height;
|
|
this.padding = padding;
|
|
this.data = data;
|
|
this.start = start;
|
|
this.end = end;
|
|
this.tickLabelFormatter = tickLabelFormatter;
|
|
this.tickLabelStyle = tickLabelStyle || {};
|
|
this.selectedTickStyle = selectedTickStyle;
|
|
this.unselectedTickStyle = unselectedTickStyle;
|
|
this.controllerCfg = controllerCfg;
|
|
this.currentSpeed = controllerCfg.speed || 1;
|
|
this.x = x;
|
|
this.y = y;
|
|
this.tooltipBackgroundColor = tooltipBackgroundColor;
|
|
this.tooltipFomatter = tooltipFomatter;
|
|
// 初始化 fontFamily,如果有浏览器,取 body 上的字体,防止文字更新时局部渲染造成的重影
|
|
this.fontFamily = typeof window !== 'undefined' ? window.getComputedStyle(document.body, null).getPropertyValue('font-family') || 'Arial, sans-serif' : 'Arial, sans-serif';
|
|
this.renderSlices();
|
|
this.initEvent();
|
|
}
|
|
TimeBarSlice.prototype.renderSlices = function () {
|
|
var _this = this;
|
|
var _a = this,
|
|
width = _a.width,
|
|
height = _a.height,
|
|
padding = _a.padding,
|
|
data = _a.data,
|
|
start = _a.start,
|
|
end = _a.end,
|
|
tickLabelFormatter = _a.tickLabelFormatter,
|
|
selectedTickStyle = _a.selectedTickStyle,
|
|
unselectedTickStyle = _a.unselectedTickStyle,
|
|
tickLabelStyle = _a.tickLabelStyle;
|
|
var realWidth = width - 2 * padding;
|
|
var fontSize = 10;
|
|
var labelLineHeight = 4;
|
|
var labelAreaHeight = 3 * padding + labelLineHeight + fontSize;
|
|
var ticksAreaHeight = height - labelAreaHeight - 2 * padding;
|
|
var gap = 2;
|
|
var ticksLength = data.length;
|
|
var tickWidth = (realWidth - gap * (ticksLength - 1)) / ticksLength;
|
|
this.tickWidth = tickWidth;
|
|
var sliceGroup = this.sliceGroup;
|
|
var tickRects = [];
|
|
var labels = [];
|
|
var startTickId = Math.round(ticksLength * start);
|
|
var endTickId = Math.round(ticksLength * end);
|
|
this.startTickRectId = startTickId;
|
|
this.endTickRectId = endTickId;
|
|
var rotate = tickLabelStyle.rotate;
|
|
delete tickLabelStyle.rotate;
|
|
data.forEach(function (d, i) {
|
|
// draw the tick rects
|
|
var selected = i >= startTickId && i <= endTickId;
|
|
var tickStyle = selected ? selectedTickStyle : unselectedTickStyle;
|
|
var rect = sliceGroup.addShape('rect', {
|
|
attrs: __assign({
|
|
x: padding + i * (tickWidth + gap),
|
|
y: padding,
|
|
width: tickWidth,
|
|
height: ticksAreaHeight
|
|
}, tickStyle),
|
|
draggable: true,
|
|
name: "tick-rect-".concat(i)
|
|
});
|
|
// draw the pick tick rects
|
|
var pickRect = sliceGroup.addShape('rect', {
|
|
attrs: {
|
|
x: padding + i * tickWidth + gap * (2 * i - 1) / 2,
|
|
y: padding,
|
|
width: i === 0 || i === ticksLength - 1 ? tickWidth + gap / 2 : tickWidth + gap,
|
|
height: ticksAreaHeight,
|
|
fill: '#fff',
|
|
opacity: 0
|
|
},
|
|
draggable: true,
|
|
name: "pick-rect-".concat(i)
|
|
});
|
|
pickRect.toFront();
|
|
var rectBBox = rect.getBBox();
|
|
var centerX = (rectBBox.minX + rectBBox.maxX) / 2;
|
|
tickRects.push({
|
|
rect: rect,
|
|
pickRect: pickRect,
|
|
value: d.date,
|
|
x: centerX,
|
|
y: rectBBox.minY
|
|
});
|
|
var label;
|
|
if (tickLabelFormatter) {
|
|
label = tickLabelFormatter(d);
|
|
if (!(0, _util.isString)(label) && label) {
|
|
// return true
|
|
label = d.date;
|
|
}
|
|
} else if (i % Math.round(ticksLength / 10) === 0) {
|
|
label = d.date;
|
|
}
|
|
if (label) {
|
|
labels.push(label);
|
|
// draw tick lines
|
|
var lineStartY = rectBBox.maxY + padding * 2;
|
|
sliceGroup.addShape('line', {
|
|
attrs: {
|
|
stroke: '#BFBFBF',
|
|
x1: centerX,
|
|
y1: lineStartY,
|
|
x2: centerX,
|
|
y2: lineStartY + labelLineHeight
|
|
},
|
|
name: 'tick-line'
|
|
});
|
|
var labelStartY = lineStartY + labelLineHeight + padding;
|
|
var text = sliceGroup.addShape('text', {
|
|
attrs: __assign({
|
|
fill: '#8c8c8c',
|
|
stroke: '#fff',
|
|
lineWidth: 1,
|
|
x: centerX,
|
|
y: labelStartY,
|
|
textAlign: 'center',
|
|
text: label,
|
|
textBaseline: 'top',
|
|
fontSize: 10,
|
|
fontFamily: _this.fontFamily || 'Arial, sans-serif'
|
|
}, tickLabelStyle),
|
|
capture: false,
|
|
name: 'tick-label'
|
|
});
|
|
var textBBox = text.getBBox();
|
|
if (textBBox.maxX > width) {
|
|
text.attr('textAlign', 'right');
|
|
} else if (textBBox.minX < 0) {
|
|
text.attr('textAlign', 'left');
|
|
}
|
|
if ((0, _util.isNumber)(rotate) && labels.length !== 10) {
|
|
var matrix = transform([1, 0, 0, 0, 1, 0, 0, 0, 1], [['t', -centerX, -labelStartY], ['r', rotate], ['t', centerX - 5, labelStartY + 2]]);
|
|
text.attr({
|
|
textAlign: 'left',
|
|
matrix: matrix
|
|
});
|
|
}
|
|
if (labels.length === 1) {
|
|
text.attr({
|
|
textAlign: 'left'
|
|
});
|
|
} else if (labels.length === 10) {
|
|
text.attr({
|
|
textAlign: 'right'
|
|
});
|
|
}
|
|
// draw tick labels
|
|
}
|
|
});
|
|
this.tickRects = tickRects;
|
|
// 渲染播放、快进和后退的控制按钮
|
|
var group = this.group;
|
|
this.currentSpeed = 1;
|
|
this.controllerBtnGroup = new _controllerBtn.default(__assign({
|
|
group: group,
|
|
x: this.x,
|
|
y: this.y + height + 5,
|
|
width: width,
|
|
height: 40,
|
|
hideTimeTypeController: true,
|
|
speed: this.currentSpeed,
|
|
fontFamily: this.fontFamily || 'Arial, sans-serif'
|
|
}, this.controllerCfg));
|
|
};
|
|
TimeBarSlice.prototype.initEvent = function () {
|
|
var _this = this;
|
|
var sliceGroup = this.sliceGroup;
|
|
sliceGroup.on('click', function (e) {
|
|
var targetRect = e.target;
|
|
if (targetRect.get('type') !== 'rect' || !targetRect.get('name')) return;
|
|
var id = parseInt(targetRect.get('name').split('-')[2], 10);
|
|
if (!isNaN(id)) {
|
|
var tickRects_1 = _this.tickRects;
|
|
// cancel the selected ticks
|
|
var unselectedTickStyle_1 = _this.unselectedTickStyle;
|
|
tickRects_1.forEach(function (tickRect) {
|
|
tickRect.rect.attr(unselectedTickStyle_1);
|
|
});
|
|
var selectedTickStyle = _this.selectedTickStyle;
|
|
tickRects_1[id].rect.attr(selectedTickStyle);
|
|
_this.startTickRectId = id;
|
|
_this.endTickRectId = id;
|
|
var ticksLength = tickRects_1.length;
|
|
var start = id / ticksLength;
|
|
_this.graph.emit(_constant.VALUE_CHANGE, {
|
|
value: [start, start]
|
|
});
|
|
}
|
|
});
|
|
sliceGroup.on('dragstart', function (e) {
|
|
var tickRects = _this.tickRects;
|
|
// cancel the selected ticks
|
|
var unselectedTickStyle = _this.unselectedTickStyle;
|
|
tickRects.forEach(function (tickRect) {
|
|
tickRect.rect.attr(unselectedTickStyle);
|
|
});
|
|
var targetRect = e.target;
|
|
var id = parseInt(targetRect.get('name').split('-')[2], 10);
|
|
var selectedTickStyle = _this.selectedTickStyle;
|
|
tickRects[id].rect.attr(selectedTickStyle);
|
|
_this.startTickRectId = id;
|
|
var ticksLength = tickRects.length;
|
|
var start = id / ticksLength;
|
|
_this.graph.emit(_constant.VALUE_CHANGE, {
|
|
value: [start, start]
|
|
});
|
|
_this.dragging = true;
|
|
});
|
|
sliceGroup.on('dragover', function (e) {
|
|
if (!_this.dragging) return;
|
|
if (e.target.get('type') !== 'rect') return;
|
|
var id = parseInt(e.target.get('name').split('-')[2], 10);
|
|
var startTickRectId = _this.startTickRectId;
|
|
var tickRects = _this.tickRects;
|
|
var selectedTickStyle = _this.selectedTickStyle;
|
|
var unselectedTickStyle = _this.unselectedTickStyle;
|
|
for (var i = 0; i < tickRects.length; i++) {
|
|
var style = i >= startTickRectId && i <= id ? selectedTickStyle : unselectedTickStyle;
|
|
tickRects[i].rect.attr(style);
|
|
}
|
|
var ticksLength = tickRects.length;
|
|
_this.endTickRectId = id;
|
|
var start = startTickRectId / ticksLength;
|
|
var end = id / ticksLength;
|
|
_this.graph.emit(_constant.VALUE_CHANGE, {
|
|
value: [start, end]
|
|
});
|
|
});
|
|
sliceGroup.on('drop', function (e) {
|
|
if (!_this.dragging) return;
|
|
_this.dragging = false;
|
|
if (e.target.get('type') !== 'rect') return;
|
|
var startTickRectId = _this.startTickRectId;
|
|
var id = parseInt(e.target.get('name').split('-')[2], 10);
|
|
if (id < startTickRectId) return;
|
|
var selectedTickStyle = _this.selectedTickStyle;
|
|
var tickRects = _this.tickRects;
|
|
tickRects[id].rect.attr(selectedTickStyle);
|
|
_this.endTickRectId = id;
|
|
var ticksLength = tickRects.length;
|
|
var start = startTickRectId / ticksLength;
|
|
var end = id / ticksLength;
|
|
_this.graph.emit(_constant.VALUE_CHANGE, {
|
|
value: [start, end]
|
|
});
|
|
});
|
|
// tooltip
|
|
var _a = this,
|
|
tooltipBackgroundColor = _a.tooltipBackgroundColor,
|
|
tooltipFomatter = _a.tooltipFomatter,
|
|
canvas = _a.canvas;
|
|
var tooltip = new _timeBarTooltip.default({
|
|
container: canvas.get('container'),
|
|
backgroundColor: tooltipBackgroundColor
|
|
});
|
|
var tickRects = this.tickRects;
|
|
tickRects.forEach(function (tickRect) {
|
|
var pickRect = tickRect.pickRect;
|
|
pickRect.on('mouseenter', function (e) {
|
|
var rect = e.target;
|
|
if (rect.get('type') !== 'rect') return;
|
|
var id = parseInt(rect.get('name').split('-')[2], 10);
|
|
var clientPoint = canvas.getClientByPoint(tickRects[id].x, tickRects[id].y);
|
|
tooltip.show({
|
|
x: tickRects[id].x,
|
|
y: tickRects[id].y,
|
|
clientX: clientPoint.x,
|
|
clientY: clientPoint.y,
|
|
text: tooltipFomatter ? tooltipFomatter(tickRects[id].value) : tickRects[id].value
|
|
});
|
|
});
|
|
pickRect.on('mouseleave', function (e) {
|
|
tooltip.hide();
|
|
});
|
|
});
|
|
// play controller events
|
|
var group = this.group;
|
|
// 播放区按钮控制
|
|
/** 播放/暂停事件 */
|
|
group.on("".concat(_constant.PLAY_PAUSE_BTN, ":click"), function () {
|
|
_this.isPlay = !_this.isPlay;
|
|
_this.changePlayStatus();
|
|
});
|
|
// 处理前进一步的事件
|
|
group.on("".concat(_constant.NEXT_STEP_BTN, ":click"), function () {
|
|
_this.updateStartEnd(1);
|
|
});
|
|
// 处理后退一步的事件
|
|
group.on("".concat(_constant.PRE_STEP_BTN, ":click"), function () {
|
|
_this.updateStartEnd(-1);
|
|
});
|
|
group.on(_constant.TIMEBAR_CONFIG_CHANGE, function (_a) {
|
|
var type = _a.type,
|
|
speed = _a.speed;
|
|
_this.currentSpeed = speed;
|
|
});
|
|
};
|
|
TimeBarSlice.prototype.changePlayStatus = function (isSync) {
|
|
if (isSync === void 0) {
|
|
isSync = true;
|
|
}
|
|
this.controllerBtnGroup.playButton.update({
|
|
isPlay: this.isPlay
|
|
});
|
|
if (this.isPlay) {
|
|
// 开始播放
|
|
this.playHandler = this.startPlay();
|
|
this.graph.emit(_constant.TIMELINE_START, null);
|
|
} else {
|
|
// 结束播放
|
|
if (this.playHandler) {
|
|
if (typeof window !== 'undefined') window.cancelAnimationFrame(this.playHandler);
|
|
if (isSync) {
|
|
this.graph.emit(_constant.TIMELINE_END, null);
|
|
}
|
|
}
|
|
}
|
|
};
|
|
TimeBarSlice.prototype.startPlay = function () {
|
|
var _this = this;
|
|
return typeof window !== 'undefined' ? window.requestAnimationFrame(function () {
|
|
var speed = _this.currentSpeed;
|
|
// 一分钟刷新一次
|
|
if (_this.frameCount % (60 / speed) === 0) {
|
|
_this.frameCount = 0;
|
|
_this.updateStartEnd(1);
|
|
}
|
|
_this.frameCount++;
|
|
if (_this.isPlay) {
|
|
_this.playHandler = _this.startPlay();
|
|
}
|
|
}) : undefined;
|
|
};
|
|
TimeBarSlice.prototype.updateStartEnd = function (sign) {
|
|
var self = this;
|
|
var tickRects = this.tickRects;
|
|
var ticksLength = tickRects.length;
|
|
var unselectedTickStyle = this.unselectedTickStyle;
|
|
var selectedTickStyle = this.selectedTickStyle;
|
|
var previousEndTickRectId = self.endTickRectId;
|
|
if (sign > 0) {
|
|
self.endTickRectId++;
|
|
} else {
|
|
tickRects[self.endTickRectId].rect.attr(unselectedTickStyle);
|
|
self.endTickRectId--;
|
|
}
|
|
// 若此时 start 与 end 不同,范围前进/后退/播放
|
|
if (previousEndTickRectId !== self.startTickRectId) {
|
|
if (self.endTickRectId < self.startTickRectId) {
|
|
self.startTickRectId = self.endTickRectId;
|
|
}
|
|
} else {
|
|
// 否则是单帧的前进/后退/播放
|
|
for (var i = self.startTickRectId; i <= self.endTickRectId - 1; i++) {
|
|
tickRects[i].rect.attr(unselectedTickStyle);
|
|
}
|
|
self.startTickRectId = self.endTickRectId;
|
|
}
|
|
if (tickRects[self.endTickRectId]) {
|
|
tickRects[self.endTickRectId].rect.attr(selectedTickStyle);
|
|
var start = self.startTickRectId / ticksLength;
|
|
var end = self.endTickRectId / ticksLength;
|
|
this.graph.emit(_constant.VALUE_CHANGE, {
|
|
value: [start, end]
|
|
});
|
|
}
|
|
};
|
|
TimeBarSlice.prototype.destory = function () {
|
|
var group = this.sliceGroup;
|
|
group.off('click');
|
|
group.off('dragstart');
|
|
group.off('dragover');
|
|
group.off('drop');
|
|
this.tickRects.forEach(function (tickRect) {
|
|
var pickRect = tickRect.pickRect;
|
|
pickRect.off('mouseenter');
|
|
pickRect.off('mouseleave');
|
|
});
|
|
this.tickRects.length = 0;
|
|
group.off("".concat(_constant.PLAY_PAUSE_BTN, ":click"));
|
|
group.off("".concat(_constant.NEXT_STEP_BTN, ":click"));
|
|
group.off("".concat(_constant.PRE_STEP_BTN, ":click"));
|
|
group.off(_constant.TIMEBAR_CONFIG_CHANGE);
|
|
this.sliceGroup.destroy();
|
|
};
|
|
return TimeBarSlice;
|
|
}();
|
|
var _default = exports.default = TimeBarSlice; |