NuclearDispersionSystem/ant-design-vue-jeecg/node_modules/@antv/component/lib/label/base.js
2023-09-14 14:47:11 +08:00

573 lines
14 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

function _createSuper(Derived) { return function () { var Super = _getPrototypeOf(Derived), result; if (_isNativeReflectConstruct()) { var NewTarget = _getPrototypeOf(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return _possibleConstructorReturn(this, result); }; }
function _possibleConstructorReturn(self, call) { if (call && (typeof call === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); }
function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; }
function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Date.prototype.toString.call(Reflect.construct(Date, [], function () {})); return true; } catch (e) { return false; } }
function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); }
function _inheritsLoose(subClass, superClass) { subClass.prototype = Object.create(superClass.prototype); subClass.prototype.constructor = subClass; subClass.__proto__ = superClass; }
var Util = require('../util');
var DomUtil = Util.DomUtil;
var Component = require('../component');
var positionAdjust = require('./utils/position-adjust');
var spirialAdjust = require('./utils/spiral-adjust');
var bboxAdjust = require('./utils/bbox-adjust');
var LAYOUTS = {
scatter: positionAdjust,
map: spirialAdjust,
treemap: bboxAdjust
};
var Label = /*#__PURE__*/function (_Component) {
_inheritsLoose(Label, _Component);
var _super = _createSuper(Label);
function Label() {
return _Component.apply(this, arguments) || this;
}
var _proto = Label.prototype;
_proto.getDefaultCfg = function getDefaultCfg() {
var cfg = _Component.prototype.getDefaultCfg.call(this);
return Util.mix({}, cfg, {
name: 'label',
/**
* label类型
* @type {(String)}
*/
type: 'default',
/**
* 默认文本样式
* @type {Array}
*/
textStyle: null,
/**
* 文本显示格式化回调函数
* @type {Function}
*/
formatter: null,
/**
* 显示的文本集合
* @type {Array}
*/
items: null,
/**
* 是否使用html渲染label
* @type {String}
*/
useHtml: false,
/**
* html 渲染时用的容器的模板,必须存在 class = "g-labels"
* @type {String}
*/
containerTpl: '<div class="g-labels" style="position:absolute;top:0;left:0;"></div>',
/**
* html 渲染时单个 label 的模板,必须存在 class = "g-label"
* @type {String}
*/
itemTpl: '<div class="g-label" style="position:absolute;">{text}</div>',
/**
* label牵引线定义
* @type {String || Object}
*/
labelLine: false,
/**
* label牵引线容器
* @type Object
*/
lineGroup: null,
/**
* 需添加label的shape
* @type Object
*/
shapes: null,
/**
* 默认为true。为false时指定直接用items渲染文本不进行config
* @type Object
*/
config: true,
/**
* 是否进行拾取
* @type Object
*/
capture: true
});
}
/*
* 清空label容器
*/
;
_proto.clear = function clear() {
var group = this.get('group');
var container = this.get('container');
if (group && !group.get('destroyed')) {
group.clear();
}
if (container) {
container.innerHTML = '';
}
_Component.prototype.clear.call(this);
}
/**
* 销毁group
*/
;
_proto.destroy = function destroy() {
var group = this.get('group');
var container = this.get('container');
if (!group.destroy) {
group.destroy();
}
if (container) {
container.parentNode && container.parentNode.removeChild(container);
}
_Component.prototype.destroy.call(this); // 要最后调用 super.destroy 否则 get 属性会无效
}
/**
* label绘制全过程
*/
;
_proto.render = function render() {
this.clear();
this._init();
this.beforeDraw();
this.draw();
this.afterDraw();
};
_proto._dryDraw = function _dryDraw() {
var self = this;
var items = self.get('items');
var children = self.getLabels();
var count = children.length;
Util.each(items, function (item, index) {
if (index < count) {
var label = children[index];
self.changeLabel(label, item);
} else {
var labelShape = self._addLabel(item, index);
if (labelShape) {
labelShape._id = item._id;
labelShape.set('coord', item.coord);
}
}
});
for (var i = count - 1; i >= items.length; i--) {
children[i].remove();
}
self._adjustLabels();
if (self.get('labelLine') || !self.get('config')) {
self.drawLines();
}
}
/**
* 更新label
* 1. 将items与group中的children对比更新/新增/删除labels
* 2. labels布局优化
* 3. 画label连接线
* 4. 绘制到画布
*/
;
_proto.draw = function draw() {
this._dryDraw();
this.get('canvas').draw();
}
/*
* 更新label
* oldLabel shape或label dom
* newLabel label data
* index items中的下标
*/
;
_proto.changeLabel = function changeLabel(oldLabel, newLabel) {
if (!oldLabel) {
return;
}
if (oldLabel.tagName) {
var node = this._createDom(newLabel);
oldLabel.innerHTML = node.innerHTML;
this._setCustomPosition(newLabel, oldLabel);
} else {
oldLabel._id = newLabel._id;
oldLabel.attr('text', newLabel.text);
if (oldLabel.attr('x') !== newLabel.x || oldLabel.attr('y') !== newLabel.y) {
oldLabel.resetMatrix();
if (newLabel.textStyle.rotate) {
oldLabel.rotateAtStart(newLabel.textStyle.rotate);
delete newLabel.textStyle.rotate;
}
oldLabel.attr(newLabel);
}
}
}
/**
* 显示label
*/
;
_proto.show = function show() {
var group = this.get('group');
var container = this.get('container');
if (group) {
group.show();
}
if (container) {
container.style.opacity = 1;
}
}
/**
* 隐藏label
*/
;
_proto.hide = function hide() {
var group = this.get('group');
var container = this.get('container');
if (group) {
group.hide();
}
if (container) {
container.style.opacity = 0;
}
}
/**
* 画label连接线
*/
;
_proto.drawLines = function drawLines() {
var self = this;
var lineStyle = self.get('labelLine');
if (typeof lineStyle === 'boolean') {
self.set('labelLine', {});
}
var lineGroup = self.get('lineGroup');
if (!lineGroup || lineGroup.get('destroyed')) {
lineGroup = self.get('group').addGroup({
elCls: 'x-line-group'
});
self.set('lineGroup', lineGroup);
} else {
lineGroup.clear();
}
Util.each(self.get('items'), function (label) {
self.lineToLabel(label, lineGroup);
});
};
_proto.lineToLabel = function lineToLabel(label, lineGroup) {
var self = this;
if (!self.get('config') && !label.labelLine) {
return;
}
var lineStyle = label.labelLine || self.get('labelLine');
var capture = typeof label.capture === 'undefined' ? self.get('capture') : label.capture;
var path = lineStyle.path;
if (path && Util.isFunction(lineStyle.path)) {
path = lineStyle.path(label);
}
if (!path) {
var start = label.start || {
x: label.x - label._offset.x,
y: label.y - label._offset.y
};
path = [['M', start.x, start.y], ['L', label.x, label.y]];
}
var stroke = label.color;
if (!stroke) {
if (label.textStyle && label.textStyle.fill) {
stroke = label.textStyle.fill;
} else {
stroke = '#000';
}
}
var lineShape = lineGroup.addShape('path', {
attrs: Util.mix({
path: path,
fill: null,
stroke: stroke
}, lineStyle),
capture: capture
}); // label 对应线的动画关闭
lineShape.name = self.get('name'); // generate labelLine id according to label id
lineShape._id = label._id && label._id.replace('glabel', 'glabelline');
lineShape.set('coord', self.get('coord'));
} // 根据type对label布局
;
_proto._adjustLabels = function _adjustLabels() {
var self = this;
var type = self.get('type');
var labels = self.getLabels();
var shapes = self.get('shapes');
var layout = LAYOUTS[type];
if (type === 'default' || !layout) {
return;
}
layout(labels, shapes);
}
/**
* 获取当前所有label实例
* @return {Array} 当前label实例
*/
;
_proto.getLabels = function getLabels() {
var container = this.get('container');
if (container) {
return Util.toArray(container.childNodes);
}
return this.get('group').get('children');
} // 先计算label的所有配置项然后生成label实例
;
_proto._addLabel = function _addLabel(item, index) {
var cfg = item;
if (this.get('config')) {
cfg = this._getLabelCfg(item, index);
}
return this._createText(cfg);
};
_proto._getLabelCfg = function _getLabelCfg(item, index) {
var textStyle = this.get('textStyle') || {};
var formatter = this.get('formatter');
var htmlTemplate = this.get('htmlTemplate');
if (!Util.isObject(item)) {
var tmp = item;
item = {};
item.text = tmp;
}
if (Util.isFunction(textStyle)) {
textStyle = textStyle(item.text, item, index);
}
if (formatter) {
item.text = formatter(item.text, item, index);
}
if (htmlTemplate) {
item.useHtml = true;
if (Util.isFunction(htmlTemplate)) {
item.text = htmlTemplate(item.text, item, index);
}
}
if (Util.isNil(item.text)) {
item.text = '';
}
item.text = item.text + ''; // ? 为什么转换为字符串
var cfg = Util.mix({}, item, {
textStyle: textStyle
}, {
x: item.x || 0,
y: item.y || 0
});
return cfg;
}
/**
* label初始化主要针对html容器
*/
;
_proto._init = function _init() {
if (!this.get('group')) {
var group = this.get('canvas').addGroup({
id: 'label-group'
});
this.set('group', group);
}
};
_proto.initHtmlContainer = function initHtmlContainer() {
var container = this.get('container');
if (!container) {
var containerTpl = this.get('containerTpl');
var wrapper = this.get('canvas').get('el').parentNode;
container = DomUtil.createDom(containerTpl);
wrapper.style.position = 'relative';
wrapper.appendChild(container);
this.set('container', container);
} else if (Util.isString(container)) {
container = document.getElementById(container);
if (container) {
this.set('container', container);
}
}
return container;
} // 分html dom和G shape两种情况生成label实例
;
_proto._createText = function _createText(config) {
// @2018-11-29 by blue.lb 这里由于使用delete导致之后的配置无法获取到point和rotate出现问题深拷贝一次比较好
var cfg = Util.deepMix({}, config);
var container = this.get('container');
var capture = typeof cfg.capture === 'undefined' ? this.get('capture') : cfg.capture;
var labelShape;
if (cfg.useHtml || cfg.htmlTemplate) {
if (!container) {
container = this.initHtmlContainer();
}
var node = this._createDom(cfg);
container.appendChild(node);
this._setCustomPosition(cfg, node);
} else {
var name = this.get('name');
var origin = cfg.point;
var group = this.get('group');
delete cfg.point; // 临时解决,否则影响动画
var rotate = cfg.rotate; // textStyle中的rotate虽然可以正常画出但是在做动画的时候可能会导致动画异常。移出在定义好shape后通过transform实现效果。
if (cfg.textStyle) {
if (cfg.textStyle.rotate) {
rotate = cfg.textStyle.rotate;
delete cfg.textStyle.rotate;
}
cfg = Util.mix({
x: cfg.x,
y: cfg.y,
textAlign: cfg.textAlign,
text: cfg.text
}, cfg.textStyle);
}
labelShape = group.addShape('text', {
attrs: cfg,
capture: capture
});
if (rotate) {
// rotate是用角度定义的转换为弧度
if (Math.abs(rotate) > Math.PI * 2) {
rotate = rotate / 180 * Math.PI;
}
labelShape.transform([['t', -cfg.x, -cfg.y], ['r', rotate], ['t', cfg.x, cfg.y]]);
}
labelShape.setSilent('origin', origin || cfg);
labelShape.name = name; // 用于事件标注
this.get('appendInfo') && labelShape.setSilent('appendInfo', this.get('appendInfo'));
return labelShape;
}
};
_proto._createDom = function _createDom(cfg) {
var itemTpl = this.get('itemTpl');
var str = Util.substitute(itemTpl, {
text: cfg.text
});
return DomUtil.createDom(str);
} // 根据文本对齐方式确定dom位置
;
_proto._setCustomPosition = function _setCustomPosition(cfg, htmlDom) {
var textAlign = cfg.textAlign || 'left';
var top = cfg.y;
var left = cfg.x;
var width = DomUtil.getOuterWidth(htmlDom);
var height = DomUtil.getOuterHeight(htmlDom);
top = top - height / 2;
if (textAlign === 'center') {
left = left - width / 2;
} else if (textAlign === 'right') {
left = left - width;
}
htmlDom.style.top = parseInt(top, 10) + 'px';
htmlDom.style.left = parseInt(left, 10) + 'px';
};
return Label;
}(Component);
module.exports = Label;